Scala学习笔记,面向对象的三大特性

作者: 化工塑胶  发布:2019-12-04

scala的官方文档写得太烂了。没办法,只能找点资料,或者看scala编译的class文件,反正最后都是java的语法,然后自己总结一下。

学习Java的进阶过程,是理解面向对象的思想,掌握面向对象的基本原则以及Java面向对象基本实现原理,熟练使用封装、继承、多态的三大特征,接下来我会带大家进一步探索Java世界的奥秘!

1、简述面向对象和面向过程的区别和联系?

为便于阅读,以下展示的编译后的class文件有做适当调整,且大部分的main函数的object编译内容没有展示

一、类和对象

类:是抽象的概念集合,表示的是一个共性的产物,类之中定义的是属性和行为(方法);
对象:对象是一种个性的表示,表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性来区分不同对象。

    面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

OO: Class & Object

1.定义类


[修饰符] class 类名
{
零到多个构造器定义...
零到多个field...
零到多个方法...
}


  • 定义field的语法格式:
    [修饰符] field 类型 field名[=默认值];
  • 定义方法的语法格式:
    [修饰符]方法返回值类型 方法名(形参列表)
    {
    //由零条到多条可执行性语句组成的方法体
    }
  • 定义构造器是一个特殊的方法:
    [修饰符]构造器名(形参列表)
    {
    //由零条到多条可执行性语句组成的构造器执行体
    }

值得指出的是,构造器既不能定义返回值类型,也不能使用void没有返回值定义构造器

定义一个类


class Person { // 类名称首字母大写
//定义两个Field
String name ;
int age ;
//定义一个tell方法
public void tell() { // 没有static
System.out.println("姓名:" + name + ",年龄:" + age) ;
}
}


    面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

Hierarchy

基本的继承结构如下图,图片来自官网:

图片 1

hierarchy.png

Object只是AnyRef的一个子类。

2.对象的产生和使用

定义和使用对象


public static void main(String args[]) {
Person per = new Person() ;// 声明并实例化对象
per.name = "张三" ;//操作属性内容
per.age = 30 ;//操作属性内容
per.tell() ;//调用类中的get()方法
}


2、对象和类的关系是?

class defination

整个class的结构内都是构造函数,构造函数的参数直接跟在申明后面。在new对象的时候,里面的所有代码都会执行。

class Person(name: String) {

    println("person info: " + info())    // 这里可以先引用info

    val age: Int = 18
    var hobby: String = "swimming"

    println("person info: " + info())    // 这里申明变量后引用

    def info(): String = {
        "name: %s; age: %d; hobby: %s".format(name, age, hobby)
    }
}

object Person {

    def main(args: Array[String]): Unit = {
        new Person("Lilei")
    }
}

// output:
// person info: name: Lilei; age: 0; hobby: null     <--- 变量都没被初始化
// person info: name: Lilei; age: 18; hobby: swimming

查看编译后的class文件可以知道大致原因:

public class Person {

    private final String name;
    private final int age;
    private String hobby;

    public int age() {
        return this.age;
    }

    public String hobby() {
        return this.hobby;
    }

    public void hobby_$eq(String x$1) {
        this.hobby = x$1;
    }

    public Person(String name) {
        this.name = name;

        Predef$.MODULE$.println(new StringBuilder().append("person info: ").append(info()).toString());

        this.age = 18;
        this.hobby = "";

        Predef..MODULE$.println(new StringBuilder().append("person info: ").append(info()).toString());
    }

    public String info() {
        return new StringOps(Predef$.MODULE$.augmentString("name: %s; age: %d; hobby: %s")).format(Predef$.MODULE$.genericWrapArray(new Object[] { this.name, BoxesRunTime.boxToInteger(age()), hobby() }));
    }

    public static void main(String[] paramArrayOfString) {
        Person$.MODULE$.main(paramArrayOfString);
    }
}

public final class Person$
{
    public static final Person$ MODULE$;

    static {
        new Person$();
    }

    public void main(String[] args) {
        new Person("Lilei");
    }

    private Person$() {
        MODULE$ = this;
    }
}

可见,在类的定义中,除了def,其他语句都是顺序执行的
而且object申明的变量和方法都是在一个object_name+$命名的类中以static形式定义出来的

二、封装

    类是抽象的,对象是具体的,是类的实例。

Extends class

语法基本和java一样,有几个前提需要注意的:

  1. var类型不能被子类重写
  2. 从父类继承的变量通过直接引用的方式使用
  3. 不能使用super去调用父类的变量,var和val类型的都不可以。
  4. 因为上一点,所以之后对此变量的所有返回值,都是重写后的值,哪怕是调用的父类方法

scala中定义的继承关系

class Singer(name: String) {

    val prefix:String = "singer: "
    var gender:String = " male"

    def info(): String = {
        prefix + name
    }
}

class Star(name: String) extends Singer(name) {

    override val prefix: String = "star: "

    override def info(): String = {
        prefix + super.info() + gender
    }
}

object Main {

    def main(args: Array[String]): Unit = {
        val star = new Star("Lilei")
        println(star.info())
    }
}

// output:
// star: star: Lilei male

这样的输出其实跟java语言的期望是不一样的。接着在编译出的class文件里找原因:

public class Singer {

    private final String name;

    public String prefix() {
        return this.prefix;
    }

    private final String prefix = "singer: ";

    public String gender() {
        return this.gender;
    }

    public void gender_$eq(String x$1) {
        this.gender = x$1;
    }

    private String gender = " male";

    public String info() {
        return new StringBuilder().append(prefix()).append(this.name).toString();
    }

    public Singer(String name) {
        this.name = name;
    }
}

public class Star extends Singer {

    public Star(String name) {
        super(name);
    }

    public String prefix() {
        return this.prefix;
    }

    private final String prefix = "star: ";

    public String info() {
        return new StringBuilder().append(prefix()).append(super.info()).append(gender()).toString();
    }
}

可以看到:

  1. 父类的属性是通过调用super()进行初始话的,这点和java一样
  2. 父类的属性都是private修饰符,对外暴露public的getter。如果子类重写父类的属性,那么对应的getter就是子类重写的方法,且只会返回子类的属性值,所以父类的就丢掉了,即子类继承的属性与父类脱离关系

1.什么是封装?

将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类的提供方法来实现对隐藏信息的操作和访问

  • 封装的好处
    只能通过规定的方法来实现访问

3、栈的特点是?存放什么内容?

Trait

trait类似于java中的接口,但支持部分的实现。一个trait其实是被编译成了对应的接口和抽象类两个文件。

trait Singer {

    val song:String = "sunshine"

    def singe(): Unit = {
        println("singing " + song)
    }

    def name(): String
}

class Star extends Singer {

    override def name(): String = {
        return "Lilei"
    }
}

object Star {

    def main(args: Array[String]): Unit = {
        val s = new Star()
        s.singe()
        println(s.name())
    }
}

// output:
// singing sunshine
// Lilei

编译出的class文件:

public abstract interface Singer {

    public abstract void com$study$classdef$witht$Singer$_setter_$song_$eq(String paramString);

    public abstract String song();

    public abstract void singe();

    public abstract String name();
}

public abstract class Singer$class {

    public static void $init$(Singer $this) {
        $this.com$study$classdef$witht$Singer$_setter_$song_$eq("sunshine");
    }

    public static void singe(Singer $this) {
        Predef..MODULE$.println(new StringBuilder().append("singing").append($this.song()).toString());
    }
}

public class Star implements Singer {
    private final String song;

    public String song() {
        return this.song;
    }

    public void com$study$classdef$witht$Singer$_setter_$song_$eq(String x$1) {
        this.song = x$1;
    }

    public void singe() {
        Singer$class.singe(this);
    }

    public Star() {
        Singer$class.$init$(this);
    }

    public String name() {
        return "Lilei";
    }
}

可以看到:

  • 在Star的构造函数中会调用trait的抽象类的static $init$()方法来初始化从trait继承来的song属性。继承来的song属性被申明到了Star中,与scala中的trait已经脱离了关系。在java中,interface里申明的都是static变量,所以scala这样实现也是很合理的。

2.实现步骤

修改属性的可见性—>设为private
创建Getter/setter方法—>用于属性的读写
在getter/setter方法中加入属性控制语句—>对属性值的合法性进行判断

  先进先出。

Mixin Class Composition

scala中除了标准的继承,还能通过with关键字组合trait类型。

class Person(name: String, age: Int) {

    println("person info: " + info())

    def info(): String = {
        "name: %s; age: %d".format(name, age)
    }
}

trait Child {

    println("child info: " + info())

    def info(): String = {
        " I am a child"
    }

    def play(): Unit
}

trait Chinese {

    println("chinese info: " + info())

    def info(): String = {
        "I am a Chinese, %s, %s".format(province(), gender)
    }

    def province(): String = {
        "Hunan"
    }

    val gender: String  = "male"
}

class Student(name: String, age: Int, grade: Int) extends Person(name, age) with Child with Chinese {

    println("student info: " + info())

    override def info(): String = {
        super.info() + " grade: %d".format(grade)
    }

    override def play(): Unit = {}
}

object Student {

    def main(args: Array[String]): Unit = {
        new Student("Lilei", 18, 1)
    }
}

// output:
// person info: I am a Chinese, Hunan, null grade: 1
// child info: I am a Chinese, Hunan, null grade: 1
// chinese info: I am a Chinese, Hunan, null grade: 1
// student info: I am a Chinese, Hunan, male grade: 1

编译的class文件是这样的:

public abstract interface Child {

    public abstract String info();

    public abstract void play();
}

public abstract class Child$class {

    public static void $init$(Child $this) {
        Predef$.MODULE$.println(new StringBuilder().append("child info: ").append($this.info()).toString());
    }

    public static String info(Child $this) {
        return " I am a child";
    }
}

public abstract interface Chinese {

    public abstract void com$study$classdef$Chinese$_setter_$gender_$eq(String paramString);

    public abstract String info();

    public abstract String province();

    public abstract String gender();
}

public abstract class Chinese$class
{
    public static String info(Chinese $this) {
        return new StringOps(Predef..MODULE$.augmentString("I am a Chinese, %s, %s")).format(Predef..MODULE$.genericWrapArray(new Object[] { $this.province(), $this.gender() }));
    }

    public static String province(Chinese $this) {
        return "Hunan";
    }

    public static void $init$(Chinese $this) {
        Predef$.MODULE$.println(new StringBuilder().append("chinese info: ").append($this.info()).toString());

        $this.com$study$classdef$Chinese$_setter_$gender_$eq("male");
    }
}

public class Person {

    private final String name;

    public Person(String name, int age) {
        Predef$.MODULE$.println(new StringBuilder().append("person info: ").append(info()).toString());
    }

    public String info() {
        return new StringOps(Predef$.MODULE$.augmentString("name: %s; age: %d")).format(Predef..MODULE$.genericWrapArray(new Object[] { this.name, BoxesRunTime.boxToInteger(this.age) }));
    }
}

public class Student extends Person implements Child, Chinese {

    private final String gender;

    public String gender() {
        return this.gender;
    }

    public void com$study$classdef$Chinese$_setter_$gender_$eq(String x$1) {
        this.gender = x$1;
    }

    public String province() {
        return Chinese.class.province(this);
    }

    public Student(String name, int age, int grade) {
        super(name, age);
        Child$class.$init$(this);
        Chinese$class.$init$(this);

        Predef$.MODULE$.println(new StringBuilder().append("student info: ").append(info()).toString());
    }

    public String info() {
        return new StringBuilder().append(Chinese.class.info(this)).append(new StringOps(Predef..MODULE$.augmentString(" grade: %d")).format(Predef..MODULE$.genericWrapArray(new Object[] { BoxesRunTime.boxToInteger(this.grade) }))).toString();
    }

    public static void main(String[] paramArrayOfString) {
        Student..MODULE$.main(paramArrayOfString);
    }

    public void play() {}
}

可以看出,这只是前面extends和trait两种情况的复合版。在子类student的构造函数中,会顺序执行super()withtrait的$init$()方法。结合前面trait的实现,可以知道一定是后一个父类/trait的变量的值会作为新值,赋值给子类的同名变量。
并且从info()的实现可以看到super引用被翻译成了Chinese,也就是后一个父类/trait定义的方法也会覆盖前一个。

3. 使用 java中的包管理类

1.包的作用

  • 管理文件
  • 解决同名文件冲突

2.定义包:package 包名
3.其他文件中使用另一个文件的包通过import关键字

全部必须是小写

  栈在程序的运行中有着举足轻重的作用。最重要的是栈保存了一个函数调用时所需要的维护信息,这常常称之为堆栈帧或者活动记录。堆栈帧一般包含如下几方面的信息:  1.函数的返回地址和参数  2. 临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。

由此可以总结出继承的特点:

  1. 继承class A extends B with C with D其实可以看作是class A extends << class B with C with D >>,切对于这个父类class B with C with D:
    1. 多重继承的关键字with只使用于trait
    2. 当出现多重继承,后面trait申明的属性和方法会覆盖前面的类/trait
      最终组成的新class,作为class A父类
  2. 父类继承的属性会作为子类独立的属性被引用,且子类无法通过super引用父类的属性。
  3. 对于方法的继承,一切同java一致

4.java中的访问修饰符

访问修饰符 本类 同包 子类 其他
private Y
默认 Y Y
protect Y Y Y
public Y Y Y Y

4、堆的特点是?存放什么内容?

Duck Typing

只要会鸭子叫,就视为鸭子。

class Person {

    def singe(): Unit = {
        println("singing")
    }
}

object Main {

    def singe(singer: {def singe():Unit}): Unit = {  // 只要实现的singe方法就可以作为参数
        singer.singe()
    }

    def main(args: Array[String]): Unit = {
        val person = new Person()
        singe(person)
    }
}

// output:
// singing

这里需要注意的是:因为得是鸭子叫,所以方法名也必须一致。

5. 内部类

内部类顾名思义就是定义在类内部的另一个类

内部类常用的几种形式分为

  • 成员内部类
  • 静态内部类
  • 方法内部类
    接下来分别讲解
    (1)内部类中最常见的就是成员内部类,也称为普通内部类。
    我们来看如下代码:

    图片 2


运行结果为:

图片 3


从上面的代码中我们可以看到,成员内部类的使用方法
1、 Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,如 public 、 protected 、 private 等
2、 Inner 类中定义的 test() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,如直接访问 Outer 类中的私有属性a
3、 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );
4、 编译上面的程序后,会发现产生了两个 .class 文件

图片 4

其中,第二个是外部类的 .class 文件,第一个是内部类的 .class 文件,即成员内部类的 .class 文件总是这样:外部类名$内部类名.class
另外,友情提示哦:
1、 外部类是不能直接使用内部类的成员和方法滴

图片 5

可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法。
2、 如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字。如:

图片 6


运行结果:

图片 7


(2)静态内部类
静态内部类是 static 修饰的内部类,这种内部类的特点是:
1、 静态内部类不能直接访问外部类的非静态成员,但可以通过** new 外部类().成员** 的方式访问
2、 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
3、 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();

图片 8

运行结果 :

图片 9

(3)方法内部类
方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。

图片 10

一定要注意哦:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。

匿名内部类这里不做讲述,如有兴趣可以自行学习

堆内存有内存地址,都是将内存的地址赋值给引用变量

Currying

柯里化。不废话了,看例子。

object Main {

    def currying(left: Int)(middle: Int)(right: Int): Int = left + middle + right

    def main(args: Array[String]): Unit = {
        val two = currying(2)(_)
        println(two(3)(4))

        val towPlusThree = two(3)
        println(towPlusThree(4))
    }
}

// output:
// 9
// 9

函数可以依次传入多个参数,切每传入一个参数就能生成一个可多次使用的新函数。

三、继承

堆内存变量无用后由垃圾回收机制回收;

Generic

比较简单的例子

class Valuable(value:Int) {

    def getValue(): Int = value
}

object Comparable {

    def add[E <: { def getValue():Int }](l: E, r: E):Int = l.getValue() + r.getValue()

    def main(args: Array[String]): Unit = {
        println(add(new Valuable(1), new Valuable(2)))
    }
}

// output:
// 3

1.什么是继承

定义一个父类,再定义一个子类,让子类继承父类,则子类可以使用父类中定义的方法和成员。但是private属性是不能继承的。

堆内存会自动初始化;

2.方法的重写

我们经常会遇到这样的方法,子类继承了父类的方法,但是对父类方法不满意,则可以重写父类的方法,这样调用时会优先调用子类重写的方法,也就是重写过的方法

继承的初始化顺序
1.初始化父类再子类
2.先初始化对象中的属性,再执行构造方法中的初始化

堆内存存放引用数据类和new出来的

3. java中final的使用

final刻意修饰类、方法、属性和变量
修饰类不允许被继承,修饰方法不允许被重写,修饰属性不允许隐式的初始化必须有值或在构造方法中赋值,修饰变量只能赋一次值变为常量

5、画出如下程序的内存结构:

4. java中的super的使用

  • 在对象的内部使用表示父类的对象
    例:如果在子类重写了父类的方法,想调用父类的方法时 super.父类的方法名()
  • 子类的构造过程中必须调用父类的构造法方法相当于默认写了super()
  • 如果显式调用构造方法(必须运用super方法调用)必须放在构造方法第一行,也就是说super()必须放在子类构造方法的第一行
  • 如果父类有一个有参的构造法方法,子类又没有显式调用构造方法则报错

//测试类和对象

public class TestObject{

public static void main(String[] args){

Car c1 = new Car();

c1.changeColor;

c1.showColor();

System.out.println(Car.tyreNum);

System.out.println(c1.tyreNum);

Car c2 = new Car();

Engine e = new Engine();

e.speed = 1000;

e.weight = 10;

c2.engine = e;

c2.color="黑色";

c2.tyreNum = 10;

System.out.println(c1.tyreNum);

}

}

class Car {

static int tyreNum=4;

Engine engine;

String color; //char sequence :字符序列

void changeColor{

color = c;

}

void showColor(){

System.out.println("我的颜色是:"+color);

}

}

class Engine{

int speed;

int weight;

}

5. java中的Object类

object类式所有类的父类,如果一个类没有使用extends关键字明确标识继承另一个类,那么这个类继承object类
object类中的方法适合所有子类。
1.tostring()方法
返回对象式哈希code码(对象地址字符串)
2.equals()方法
比较的是对象的引用是否指向同一块内存地址
Dog dog = new Dog();
Dog dog2 = new Dog();
dog,dog2对象其实是dog指向了两个个不同的内存地址
if(dog.equals(dog2)){
System.out.println("地址值相同");
}else{System.out.println("地址值不相同");}
结果:地址值不相同

图片 11

四、多态

对象的多种形态

6、局部变量、成员变量、静态变量分别怎么声明?

1.引用多态

父类的引用可以指向本类的对象
父类的引用可以指向子类的对象

  局部变量:在方法或代码块中声明的变量

2.方法多态

创建本类的对象时,调用本类方法
创建子类对象时调用子类的重写方法或继承的方法

  成员变量:在类中生命的变量称为 成员变量

3. java 中的抽象类

就像公交车,出租车,摩托车等可以抽象出一个公共的特征是交通工具,有相同的使用方法是出行,那么类似的我们可以把许多类抽象出一个公共类,里面定义共有的成员变量以及方法,这样的类就是抽象类。定义一个抽象类,包括我们在c++中定义虚函数,这样的模块化使用不仅减少了代码的重复率,还减轻了开发人员的工作量,所以在面向对象的编程思想中,抽象类是一个很重要的运用。

  • 抽象类的定义
    abstract class Instrument {
    // 抽象类中可以有非抽象方法。
    private int i;
    public abstract void play(Note n);
    public String what() { return "Instrument"; }
    public abstract void adjust();
    }

  静态变量:用static 修饰额成员变量,也叫类变量

4.java 中的接口

接口则是一个抽象类型,是抽象方法的集合,接口是为了实现不能抽象到一个类的两个有公共方法的类的方法的抽象。比如飞机和鸟,两个都具有相同的方法就是飞行,但是我们不能将飞机和鸟抽象到一个类里,那么飞机是一个类,鸟是一个类,同时我们定义一个接口,接口里抽象了飞行这个方法,则飞机和鸟两个类都可以通过调用这个接口实现飞行这个方法的实例化。

  • 定义接口
    [修饰符]interface 接口名[extends 父接口1,extends 父接口2,....]
    {
    零到多个常量定义...public static final
    零到多个抽象方法的定义...public abstract
    }
  • 继承父类实现接口的语法为:
    [修饰符]class 类名 extends 父类 implements 接口1,接口2 。。

    类体部分//如果继承了抽象类,需要实现继承的抽象方法;要实现接口中的抽象方法

7、局部变量使用之前,必须要手动初始化吗?

5.抽象类和接口的区别

要知道接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
7、抽象类里可以没有抽象方法
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。

end.

作者有话说:
我也是一个java方向技术小白,所以文章更多的是知识点干货内容,我会往自己的理解方面更多的努力,此篇文章希望可以给予有一定的java语言基础的程序猿们更多的帮助。如果喜欢我的文章记得关注我并给我点个赞哦~

8、如果不手动指定成员变量的值,系统将会自动初始化。那么初始化的规则是?

  整型初始化为0;

  浮点型初始化为0.0

  引用数据类型初始化为null;

  boolean型初始化为false;

  char 型初始化为uoooo

8、成员变量从属于谁? 静态变量又叫什么以及从属于谁? 局部变量从属于谁?

成员变量从属于对象;

静态变量也叫类变量,属于类;

局部变量的从属于方法或者代码块

9、构造方法的作用是两个:一个构造类的对象,另一个作用是初始化对象的属性。这
种说法对不?

10、构造方法的名称必须保持跟类名一致吗?

  必须一致

11、构造方法有没有返回值?详细用文字描述返回值问题。

  构造方法没有返回值,也不能加void

12、构造方法如何被调用?

  实例化对象的时候调用,new

13、构造方法中能不能有return语句?

  不能

14、系统一定会给我们添加无参数的构造方法吗? 请详细解释。

  没有构造方法的时候,java会默认添加无参构造方法

15、下面的代码有什么问题:

class Computer {

int price;

int type;

String brand;

public void start(){

System.out.println("启动中....");

}

computer(int _price, int type, String _brand){

//this.price = price;

price = _price;

type = type;

brand = _brand;

}

}

  当局部变量的名称与成员变量的名称相同时,使用this代表成员变量

16、设计一个类代表二维空间的一个点

17、设计一个类代表二维空间的一个圆。要求两个成员变量。一个是圆心,一
个是半径提供计算面积的方法。

18、为上述Cricle类添加一个方法,计算一个点是否在圆(Cricle

对象)内,并写程序验证

19、构造方法能不能重载?

  可以

20、this在普通方法中,指的是哪个对象?在构造方法中,指的是?

  this在普通方法中总是指向调用该方法的对象

  this在构造方法中总是指向正要初始化的对象

21、static变量在内存中放置在哪个区? static变量和方法为什么被称为类变量和类方
法?可以被该类所有对象共享吗?

  static 变量存在数据区

  static修饰的归类所有,可以用类名调用

  可以被该类所有对象共享

22、静态初始化块和main方法哪个先被执行?

  静态初始化代码块先执行

23、一个构造方法调用另一个构造方法怎么调用? this(),这样的调用方式必须位于第
一句吗?

  this()调用本类的无参构造方法

  this 调用本类的带参构造方法

  super(),super则是调用父类的;

  this()调用必须位于构造方法的第一句

24、package的两个作用是什么?

本文由88必发手机版发布于化工塑胶,转载请注明出处:Scala学习笔记,面向对象的三大特性

关键词:

上一篇:没有了
下一篇:没有了