Java学习苦旅(十二)——继承

本篇博客将介绍Java中的继承。

文章目录

  • 什么是继承
  • 语法规则
    • 基本语法
    • super关键字
    • protected关键字
    • final关键字
  • 组合
  • 结尾

什么是继承

我们可以先来看这样一段代码:

class Dog {
    public String name;
    public int age;
    
    public void eat() {
        System.out.println("吃");
    }
}

class Bird {
    public String name;
    public int age;
    
    public void eat() {
        System.out.println("吃");
    }
    
    public void fly() {
        System.out.println("飞");
    }
}

我们可以发现,这两个类存在很多共性,比如都有name,age,还有eat方法。那么我们能不能想个办法,把这些共性放到一起,如果以后有需要,直接调用即可。这种方法是存在的,它就是我们今天要讲的继承。

继承是对共性的抽取,使用extends关键字进行处理的。 例如:

class Animal {
    public String name;
    public int age;
    
    public void eat() {
        System.out.println("吃");
    }
}

class Dog extends Animal {
    
}

class Bird extends Animal {
    public void fly() {
        System.out.println("飞");
    }
}

此时,Dog和Bird被称为 子类派生类 。Animal被称为 父类基类超类 。extends就代表 继承

从逻辑上讲, Dog 和 Bird 都是一种 Animal (is - a 语义)。

继承的意义:可以对代码重复使用。

语法规则

基本语法

class 子类 extends 父类 {
    
}

注意事项:

  • 使用 extends 指定父类。

  • Java 中一个子类只能继承一个父类(而C++/Python等语言支持多继承)。

  • 子类会继承父类的所有 public 的字段和方法。

  • 对于父类的 private 的字段和方法,子类中是无法访问的。

  • 子类的实例中,也包含着父类的实例。可以使用 super 关键字得到父类实例的引用。

super关键字

子类构造的同时,要先帮助父类来进行构造。例如:

class Animal {
    public String name;
    public int age;
    
    public void eat() {
        System.out.println("吃");
    }
}

class Dog extends Animal {
   public Dog(String name, int age) {
       super(name,age);//调用父类带有两个参数的构造方法
   }
}

class Bird extends Animal {
    public String wing;
    
    public Bird(String name,int age,String wing) {
        super(name,age);
        this.wing = wing;
    }
    
    public void fly() {
        System.out.println(super.name + "飞" + super.age);
    }
}

super不能出现在静态方法当中。

protected关键字

  • 对于类的调用者来说,protected修饰的字段和方法是不能访问的。
  • 对于类的 子类同一个包的其他类 来说,protected修饰的字段和方法是可以访问的。

例如:

class Animal {
    protected String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    public void eat(String food) {
        System.out.println(this.name + "吃" +food);
    }
}

class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }
    
    public void fly() {
        System.out.println(name + "飞");
    }
} 

小结:

  • private:类内部能访问,类外部不能访问。

  • 默认(也叫包访问权限):类内部能访问,同一个包中的类可以访问,其他类不能访问。

  • protected:类内部能访问,子类和同一个包中的类可以访问,其他类不能访问。

  • public:类内部和类的调用者都能访问。

什么时候下用哪一种呢?

我们希望类要尽量做到 “封装”,即隐藏内部实现细节,只暴露出 必要 的信息给类的调用者。因此我们在使用的时候应该尽可能的使用 比较严格 的访问权限。例如,如果一个方法能用 private,就尽量不要用public。

另外,还有一种 简单粗暴 的做法:将所有的字段设为 private,将所有的方法设为 public。不过这种方式属于是对访问权限的滥用, 还是更希望大家能写代码的时候认真思考,该类提供的字段方法到底给 “谁” 使用(是类内部自己用,还是类的调用者使用,还是子类使用)。

final关键字

时刻牢记,我们写的类是现实事物的抽象。而我们真正在公司中所遇到的项目往往业务比较复杂,可能会涉及到一系列复杂的概念,都需要我们使用代码来表示,所以我们真实项目中所写的类也会有很多. 类之间的关系也会更加复杂。但是即使如此,我们并不希望类之间的继承层次太复杂。一般我们不希望出现超过三层的继承关系。如果继承层次太多,就需要考虑对代码进行重构了。如果想从语法上进行限制继承,就可以使用 final 关键字。

例如:

final public class Animal {
    ...
}

public class Bird extends Animal {
    ...//编译错误
}

组合

组合与继承类似,但却有所不同。我们可以看个例子:

public class Student {
    ...
}

public class Teacher {
    ...
}

public class School {
    public Student[] students;
    public Teacher[] teachers;
}

由此可知,组合也是一种表达类之间关系的方式,也是能够达到代码重用的效果。但是组合并没有涉及到特殊的语法(诸如 extends 这样的关键字),仅仅是将一个类的实例作为另外一个类的字段。这是我们设计类的一种常用方式之一。

结尾

本篇博客到此结束

上一篇博客:Java学习苦旅(十一)——你好,买“包”不?

下一篇博客预告:Java学习苦旅(十三)——多态

你可能感兴趣的:(Java学习苦旅,java,开发语言,后端)