Java(八)

面向对象

在面向对象中,class和instance是“模板”和“实例”的关系;

class是一种数据类型,对应的instance就是这中数据类型的实例;

class定义field,在每个instance都会拥有各自的field,且互不干扰;

通过new来创建instance,然后用变量指向它;

访问实例字段的方法,变量名.字段名;

指向instance的变量都是引用变量。

练习:

请定义一个City类,该class具有如下字段:

  • name: 名称,String类型
  • latitude: 纬度,double类型
  • longitude: 经度,double类型
public class Test {
    public static void main(String[] args){
        City bj = new City();
        bj.name = "北京";
        bj.latitude = 39.903;
        bj.longitude = 116.401;
        System.out.printf(bj.name);
        System.out.printf("location:"+bj.latitude+","+bj.longitude);
    }
}

public class City {
    public String name;
    public double latitude; //纬度
    public double longitude;//经度
}

方法

class里的field定义为private时,外部无法访问class里的field,所以我们需要method来让外部代码可以间接修改field;

定义方法的语法:

修饰符 方法返回类型 方法名(方法参数列表){

  若干方法实现语句;

  return 方法返回值;

}

如果没有方法返回值,返回类型设置为void,可以省略return

public class Test {
    public static void main(String[] args){
        Person person = new Person();
        person.setName("xiaoming");
        person.setAge(23);
    }
}

public class Person {
    private String name;
    private int age;

    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }

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

    public void setAge(int age){
        if (age < 0 || age > 100){
            throw new IllegalArgumentException("invalid age value");
        }
        this.age = age;
    }
}

外部代码不能直接修改private字段,但是可以通过setName()、setAge()来间接修改private字段,外部代码也不能直接读取private字段,但是可以通过getName、getAge间接获取private字段。

调用方法的语法是:实例变量名.方法名(参数);

private方法

私有方法不允许外部调用,只能在类内部被调用。

私有方法要在方法前面加上private;

this变量

this是方法里的一个隐含变量,this始终指向当前实例;

如果命名没有冲突时,可以省略this,但是如果局部变量和字段重名,局部变量的优先级要高,就必须加上this;

方法参数

方法可以包含0或者任意个参数;调用方法时,必须按照参数的定义--传递;

可变参数

可变参数用 类型... 定义,可变参数相当于数组类型; eg:String...

class Group {
    private String[] names;

    public void setNames(String... names) {
        this.names = names;
    }
}

但是在上述的代码中,调用方需要自己先构造String[];

eg:Group g = new Group();

g.setNames(new String[]){"xiaoming","tom"}

另一个问题:传入方可以传入一个null:

Group g = new Group();
g.setNames(null);

可变参数可以保证不能传null,因为传入0个参数时,接收到的实际值是一个空数组而不是null

参数绑定

基本类型的参数绑定

public class Main {
    public static void main(String[] args) {
        Person p = new Person();
        int n = 15; // n的值为15
        p.setAge(n); // 传入n的值
        System.out.println(p.getAge()); // 15
        n = 20; // n的值改为20
        System.out.println(p.getAge()); // 15
    }
}

class Person {
    private int age;

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

    public void setAge(int age) {
        this.age = age;
    }
}

修改局部外部变量n之后,不影响实例p的age字段,原因是setAge()方法获得的参数,复制了n的值,因此p.age和局部变量n互不影响。

基本类型参数的传递,是调用方的复制。双方各自修改后,互不影响。

引用类型参数绑定

public class Main {
    public static void main(String[] args) {
        Person p = new Person();
        String[] fullname = new String[] { "Homer", "Simpson" };
        p.setName(fullname); // 传入fullname数组
        System.out.println(p.getName()); // "Homer Simpson"
        fullname[0] = "Bart"; // fullname数组的第一个元素修改为"Bart"
        System.out.println(p.getName()); // "Homer Simpson"还是"Bart Simpson"?
    }
}

class Person {
    private String[] name;

    public String getName() {
        return this.name[0] + " " + this.name[1];
    }

    public void setName(String[] name) {
        this.name = name;
    }
}

引用类型参数的传递,调用方的变量,和接收方的参数变量,指向的是同一个对象。双方任意一方对这个对象的修改,都会影响对方。

构造方法

创建对象实例时,就把内部字段全部初始化为合适的值;

构造方法的名称就是类名,在方法内部,可以编写任意语句。但是和普通方法相比,构造方法没有返回值,也没有void,调用构造方法,必须用new操作符。

public static void main(String[] args){
      Person person = new Person("Tom",11);
      System.out.println(person.getName());
      System.out.println(person.getAge());
    }
}
public class Person {
    private String name;
    private int age;


    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    
    public String getName(){
        return this.name;
    }

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

 默认构造方法

所有的class都有构造方法,如果一个类没有定义构造方法,编译器会自动生成一个默认构造方法,它没有参数,也没有执行语句;如果我们自定义了一个构造方法,编译器不再自动创建默认构造方法。

如果想两个构造方法都使用,那么就把两个构造方法都定义出来。

构造方法中没有初始化字段时,引用类型的默认值是null,数值类型的字段用默认值, int类型的默认值是0,布尔类型的默认值是false。

既对字段初始化,又在构造方法里对字段初始化,字段的初始值由构造方法的代码决定。

java中的执行顺序:先初始化字段,然后执行构造方法。

多构造方法

一个构造方法可以调用其他构造方法,这样的目的是便于代码复用。调用语法是this(...)

练习:请给Person类增加(Sting,int)的构造方法:

public class Test {
    public static void main(String[] args){
    Person ming = new Person("Tim",12);
    System.out.println(ming.getName());
    System.out.println(ming.getAge());
    }
}

public class Person {
    private String name;
    private int age;


    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }


    public String getName(){
        return name;
    }

    public int getAge(){
        return age;
    }
}

 

posted @ 2021-03-16 17:50  小小日常  阅读(154)  评论(0编辑  收藏  举报