《廖雪峰Java教程》——面向对象基础(1)

参考资料:

方法

Java 的方法允许定义可变参数

class Group {
    private String[] names;

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

可变参数代替数组类型的好处有:

  • 可变参数的传参形式更简单:

    Group g = new Group();
    g.setNames("Xiao Ming", "Xiao Hong", "Xiao jun");	// 可变参数
    g.setNames(new String[] {"Xiao Ming", "Xiao Hong", "Xiao jun"});	// 数组参数
    
  • 可变参数可以避免传入 null

基本类型值传递,引用类型引用传递。

构造方法

class Person {
    private String name = "Unamed";
    private int age = 10;

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

在Java中,创建对象实例的时候,先初始化字段,例如,int age = 10; 表示字段初始化为 10 ,然后执行构造方法的代码进行初始化。

方法重载

和 C++ 类似

继承

使用 extends 关键字实现继承:

class Person {
    private String name;
    private int age;

    public String getName() {...}
    public void setName(String name) {...}
    public int getAge() {...}
    public void setAge(int age) {...}
}

class Student extends Person {
    // 不要重复name和age字段/方法,
    // 只需要定义新增score字段/方法:
    private int score;

    public int getScore() {}
    public void setScore(int score) {}
}

在Java中,没有明确写 extends 的类,编译器会自动加上 extends Object ,所以除了 object 类,任何类都会继承自某个类。

Java只允许一个class继承自一个类,因此,一个类有且仅有一个父类

super

super 关键字表示父类:

class Person {
    protected String name;
    protected int age;

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

class Student extends Person {
    protected int score;

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

上述代码会编译报错,这是因为在 Java 中,任何 class 的构造方法,第一行语句必须是调用父类的构造方法。如果没有明确地调用父类的构造方法,编译器会帮我们自动加一句 super(); 由于 Person 类没有无参的构造方法,所以编译失败。

我们可以使用 super 显示调用父类的构造方法:

class Student extends Person {
    protected int score;

    public Student(String name, int age, int score) {
        super(name, age); // 调用父类的构造方法Person(String, int)
        this.score = score;
    }
}

阻止继承

使用 final 关键字修饰不能被继承的类。

从 Java 15 开始,可以使用 sealedpermits 来明确指定能够继承该 class 的类:

public sealed class Shape permits Rect, Circle, Triangle {
    ...
}

向上转型

可以让父类型的引用变量指向子类型的实例。

向下转型

Person p1 = new Student(); // upcasting, ok
Person p2 = new Person();
Student s1 = (Student) p1; // ok
Student s2 = (Student) p2; // runtime error! ClassCastException!

向下转型能否成功由变量实际所指的类型决定,可以使用 instanceof 加以判断:

Person p = new Person();
System.out.println(p instanceof Person); // true
System.out.println(p instanceof Student); // false

Student s = new Student();
System.out.println(s instanceof Person); // true
System.out.println(s instanceof Student); // true

Student n = null;
System.out.println(n instanceof Student); // false

instanceof 实际上判断一个变量所指向的实例是否是指定类型,或者这个类型的子类。如果一个引用变量为 null ,那么对任何 instanceof 的判断都为 false

从 Java 14 开始,判断 instanceof 后可以直接转型为指定变量:

Object obj = "hello";
if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.toUpperCase());
}

// 可以简写为

Object obj = "hello";
if (obj instanceof String s) {
    System.out.println(s.toUpperCase());
}

区分继承和组合

继承是 is 关系,组合是 has 关系。

多态

可以使用 @Override让编译器帮助检查是否进行了正确的覆写:

class Person {
    public void run() {}
}

public class Student extends Person {
    @Override // Compile error!
    public void run(String s) {}
}

实例方法调用是基于运行时的实际类型的动态调用,而非变量的声明类型。

覆写Object方法

Object 定义了几个重要的方法:

  • toString() :把 instance 输出为 String
  • equals() :判断两个 instance 是否逻辑相等;
  • hashCode() :计算一个 instance 的哈希值。

final

如果一个父类不允许子类对它的某个方法进行覆写,可以把该方法标记为 final

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值