持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
1️⃣前言
大家好,我是翼同学。今天笔记的内容是:
- 类的继承
2️⃣内容
2.1、概述
在面向对象的程序设计中,继承是一个重要的概念。继承允许我们创建有等级层次的类。
当一个类是从父类继承而来的,就意味着这两个类存在了is-a关系。is-a关系是继承的一个特征。
具体来说,继承就是子类可以继承父类的特征和行为,这样使得子类可以拥有父类的属性和方法。
比如说老虎类和狮子类都可以继承与哺乳动物类,使得子类具有父类的相同特征,同时又可以定义自己的特征。
2.2、extends关键字
在Java中,我们使用extends关键字来表明一个;类是从另一个类继承而来的。
举个例子:
下面的代码表示Manager类继承于Employee类:
class Manager extends Employee{
// 添加一些属性和方法
...
}
事实上Java定义继承的方式和C++的很像,只不过Java通过关键字extends代替了C++中的冒号:。另外,Java中没有私有继承和保护继承,所有的继承都是公有继承。
2.3、父类和子类
关键字extends表明了此时创建的类继承于(或者说派生于)已存在的类。
我们将这个已存在的类称为父类、超类或者基类。新创建的类称为子类、派生类或者孩子类。
事实上,子类封装的数据会更多,功能也比父类丰富。因此我们说,父类更加通用,子类更加具体。我们会将通用的方法放在父类中,而具有特殊功能的方法放在子类中。
子类可以调用父类中的方法,因为子类自动继承了父类中的方法和属性。当我们在子类定义新的方法时,子类的对象可以调用,但父类的对象却无法使用;并且需要注意,子类不能删除父类中的任何属性或方法。
2.4、super关键字
举个例子:现在我们有一个Employee父类的部分代码如下:
class Employee{
// 属性
private double salary;
// 方法
public double getSalary(){
return salary;
}
}
此时定义一个子类Manager的部分代码如下:
class Manager extends Employee{
// 属性
private double bonus;
}
我们在Manager类中新定义了一个属性bonus,此时就需要重新编写一个getSalary()方法来覆盖父类中的方法。
class Manager extends Employee{
// 属性
private double bonus;
// 方法
public double getSalary(){
return salary + bonus;
}
}
但是,上面的代码无法运行。这是因为子类的对象无法访问父类中的私有属性。只有父类中的方法才能访问父类的私有属性,这一点需要注意。
但是,如果我们借助父类的公有方法来调用父类的属性,是否能成功呢?
class Manager extends Employee{
public double getSalary(){
double mySalary = getSalary();
return mySalary;
}
}
很遗憾,上述的代码仍然无法运行:子类在调用getSalary()方法时会导致无限次的调用自己,因为子类也有一个getSalary()方法,但我们希望调用的是父类中的getSalary()方法,因此运行后程序就会崩溃。
为了解决这种问题,我们可以使用关键字super。
下面是子类中getSalary()方法的正确写法:
class Manager extends Employee{
public double getSalary(){
double mySalary = super.getSalary();
return mySalary;
}
}
简单来说,super关键字不是一个对象的引用,而是用于指示编译器调用父类方法的特有关键字,有点像C++中用::操作符来访问父类中的方法。
另外,super关键字在构造器方面的应用也很多。
比如说我们现在有一个父类MyBase,他的构造器如下所示:
public MyBase(int i, String s){
data = i;
str = s;
}
然后有一个子类MySon继承于父类MyBase,子类有一个新定义的属性ch,则子类的构造器可以这么写:
public MySon(int i, String s, char c){
super(i, s);
ch = c;
}
语句super(i, s);是调用父类构造器的简写形式。
由于子类的构造器无法访问父类的私有属性,因此必须利用父类的构造器来初始化父类的私有属性,也就是在子类中利用super关键字来实现对父类构造器的使用。
如果子类没有显示地调用父类的构造器,则会自动调用父类默认的无参构造器。但注意,如果父类没有无参构造器,并且子类又没有调用父类的其他构造器,此时Java编译器会报错。
2.5、多重继承
在继承机制方面与C++相比,Java是不支持多继承,这与C++不同。但是Java支持多重继承。
怎么理解呢?
下面代码属于多重继承,Java是支持的:
// C类继承于B类,而B类又继承于A类
class A {}
class B extends A {}
class C extends B {}
而多继承对于Java来说是不支持的,比如:
// C类想继承于A类和B类,这是错误的
class A {}
class A {}
class C extends A,B {}
另外,如果是不同子类继承于同一个父类的话,Java是支持的。
比如:
class A {}
class B extends A {}
class C extends A {}
2.6、小结
继承是java面向对象编程技术的一块基石,继承机制允许我们创建分等级层次的类。 对于继承:
- 子类可以拥有父类的非
private的属性和方法; - 子类可以定义自己的属性和方法,即丰富父类,进行一定的扩展;
- 子类可以重写父类的方法;
- Java的继承属于单继承,不支持多继承,但是可以多重继承;
3️⃣写在最后
好了,今天的笔记就记到这里。