一篇文章带你彻底理解继承(Java面向对象的基石)——菜鸟教程学习记录
基本概念:
**继承是Java面向对象编程技术的一块基石,因为它允许创建“分等级层次的类“。**它允许一个类(称为子类或派生类)继承另一个类(称为父类、超类或基类)的属性和方法。
怎么理解分等级层次的类呢?
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
简单来讲:
通过继承,子类可以获得父类的非私有成员变量和非私有方法,包括字段、方法和构造函数。子类可以使用继承来扩展父类的功能,添加新的字段和方法,或者覆盖父类的方法以提供自定义的实现。
如下图这就是分等次层次的类:
可以点击链接去菜鸟教程看这一图的详解,如果简单理解的话那就是:父类更通用,子类更具体。
类的继承格式
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般语法如下:
//类的继承格式
class 父类 {
}
class 子类 extends 父类 {
}
为什么需要继承?
从上面的例子中我们可以看出:
继承它提供了以下几个主要的好处和理由:
- **代码重用:**继承允许子类获得父类的属性和方法,避免了重复编写相同的代码。子类可以直接使用父类的成员,从而实现代码的重用和简化。
- 扩展性:通过继承,可以在现有的类的基础上进行扩展,添加额外的功能和特性。子类可以继承父类的行为,并且可以在此基础上添加新的行为或修改现有行为,从而实现类的功能扩展。
- **分类和抽象:**继承提供了一种分类和抽象的方式。通过将共同的属性和方法抽取到一个父类中,可以更好地组织和管理代码,使代码结构更加清晰和易于理解。
- **多态性:继承是实现多态性的基础。**通过将子类的对象赋值给父类的引用变量,可以在运行时根据对象的实际类型调用相应的方法。这种多态性提高了代码的灵活性和可扩展性。
- **继承关系的建模:**继承可以用于建立对象之间的关系,并模拟现实世界中的相关概念。例如上面的例子一样,我们可以通过继承建立"动物"和"食肉动物"之间的关系,其中"食肉动物"是"动物"的子类。
**PS:虽然继承有好处,但是过度的继承可能导致类之间的紧密耦合,使代码难以理解和维护。**因此,在使用继承时需要遵循面向对象编程的原则和最佳实践,确保继承关系合理、可靠和易于扩展。简单来说就是:合理暴露,合理开放!
继承类型
需要注意的是 “Java 不支持多继承,但支持多重继承。”
继承的特性
- 子类拥有父类非 private 的属性、方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
继承关键字extends和implements
在Java中,extends
和implements
关键字都用于实现类之间的继承关系,但它们有不同的应用场景和语义。
-
**
extends
关键字用于实现类与类之间的继承关系。**一个类可以继承另一个类的属性和方法,从而扩展该类的功能。在继承关系中,子类(派生类)通过使用extends
关键字指定一个父类(基类、超类),从而继承父类的非私有成员。Java中的继承是单继承的,即一个类只能有一个直接的父类。例如:
class Animal { // 父类 Animal 的属性和方法 } class Dog extends Animal { // 子类 Dog 继承了父类 Animal 的属性和方法,并可以进行扩展 }
-
implements
关键字用于实现类与接口之间的继承关系。接口定义了一组规范,而类通过实现接口来提供具体的实现。一个类可以实现一个或多个接口(多个接口的实现使用;隔开,变相让java巨头多继承特性),从而获得接口中定义的方法,并需要提供这些方法的具体实现。“接口的方法在实现类中必须被重写”。例如:
interface Flyable { void fly(); // 接口 Flyable 定义了飞行的规范 } class Bird implements Flyable { public void fly() { // 实现类 Bird 提供了飞行方法的具体实现 } }
extends和implements的区别小结:
extends
用于实现类与类之间的继承关系implements
用于实现类与接口之间的继承关系。- 通过继承和实现接口,可以实现代码的重用、扩展性和多态性等面向对象编程的特性。
super 与 this 关键字
**super关键字:**我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。
[这里还涉及一个向上转型和向下转型的知识点]((14条消息) Java-高级编程继承中向上转型(Upcasting)和向下转型(Downcasting)的简单理解_java父类向下转型_Stevedash的博客-CSDN博客)
这是我前面的文章已经讲过的知识点。
final 关键字
final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。
final 含义为 “最终的”。
使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:
-
声明类:
final class 类名 {//类体}
-
声明方法:
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
注: final 定义的类,其中的属性、方法不是 final 的。
解释如下:
当一个类被声明为final
时,该类本身不能被继承,但其中的属性和方法并不会自动成为final
。”final
类中的属性和方法可以根据需要进行修改或重写。“
简单且具体的来讲:
- 对于属性:
final
类中的属性没有被隐式地设为final
,因此可以通过在构造函数或其他方法中赋值来更改它们的值。 - 对于方法:
final
类中的方法也没有被隐式地设为final
,因此子类仍然可以覆盖和重写这些方法。
如果希望某个属性或方法在final
类中无法被修改或重写,我们可以使用final
修饰符来标记它们,例如
final int x = 10;//最终量
final void doSomething() { ... }`。//最终方法
构造器
子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。
- 简单理解:
如果“父类的构造器带有参数”,则必须在子类的构造器中显式地”通过 super 关键字调用父类的构造器并配以适当的参数列表,才能够调用到父类的构造器“。 - 如果“父类构造器没有参数”,则在子类的构造器中不需要使用 super 关键字调用父类构造器,“系统会自动调用父类的无参构造器。”
具体例子如下:
class SuperClass {
private int n;
SuperClass(){
System.out.println("SuperClass()");
}
SuperClass(int n) {
System.out.println("SuperClass(int n)");
this.n = n;
}
}
// SubClass 类继承
class SubClass extends SuperClass{
private int n;
SubClass(){ // 自动调用父类的无参数构造器
System.out.println("SubClass");
}
public SubClass(int n){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass(int n):"+n);
this.n = n;
}
}
// SubClass2 类继承
class SubClass2 extends SuperClass{
private int n;
SubClass2(){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass2");
}
public SubClass2(int n){ // 自动调用父类的无参数构造器
System.out.println("SubClass2(int n):"+n);
this.n = n;
}
}
public class TestSuperSub{
public static void main (String args[]){
System.out.println("------SubClass 类继承------");
SubClass sc1 = new SubClass();
SubClass sc2 = new SubClass(100);
System.out.println("------SubClass2 类继承------");
SubClass2 sc3 = new SubClass2();
SubClass2 sc4 = new SubClass2(200);
}
}
输出结果为:
------SubClass 类继承------
SuperClass()
SubClass
SuperClass(int n)
SubClass(int n):100
------SubClass2 类继承------
SuperClass(int n)
SubClass2
SuperClass()
SubClass2(int n):200
结尾语:记录于2023年7月31号21时00分,以上仅为个人在Java继承——面向对象的学习过程中遇到的问题,还有记录的个人想法,有错误欢迎指出,希望对您有帮助,感谢观看!如果可以的话,点点赞,点点关注