目录

一:继承(面向对象的关键语法)

1.1 为什么需要继承

1.2 继承概念

1.3:继承的语法

1.4 父类成员访问

1.4.1 子类中访问父类的成员变量

1.4.2 子类中访问父类的成员方法

1.5 super关键字

1.6 子类构造方法

1.7 super和this

1.8 protected 关键字(就是与privat和public并列关系)

1.8.1:default使用

1.8.2:protected的实际应用

1.9继承方式

1.10:final关键字

1:使用final修饰关键字,改变了不能被修改。

2:使用final修饰类(此时该类就不能被继承)

1.11:继承和组合

二:总结


一:继承(面向对象的关键语法)

把公共的内容,单独提取出来作为父亲,其他个性化的东西,基于“父亲”派生出“子类”个性化的东西放到子类中,这样做可以使代码复用。

1.1 为什么需要继承

java中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,则可以用来表示现实中的实体,但是现实世界错综复杂,事物之间可能会存在一些关联,那在设计程序是就需要考虑

使用Java语言来进行描述,就会设计出:
// Dog.java
public class Dog{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep(){
System.out.println(name + "正在睡觉");
}
void Bark(){
System.out.println(name + "汪汪汪~~~");

}

}
// Cat.Java
public class Cat{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep()
{
System.out.println(name + "正在睡觉");
}
void mew(){
System.out.println(name + "喵喵喵~~~");

}
}

通过观察上述代码会发现,猫和狗的类中存在大量重复,

那能否将这些共性抽取呢?面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复用。

1.2 继承概念

父类:提取出来的公共代码
子类:个性化代码,继承父类(父类的属性和方法,就能重用起来)
通过父类产生子类的过程,就叫派生
父类派生出来子类   子类继承父类

父类叫法:父类 基类、超类 翻译后:parentclass、base class 、 super class
子类叫法:子类 派生类    翻译后: child class           derived class 、sub class
这种3v3的关系

上述图示中,Dog和Cat都继承了Animal类,其中:Animal类称为父类/基类或超类,Dog和Cat可以称为Animal的子类/派生类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。
从继承概念中可以看出继承最大的作用就是:实现代码复用,还有就是来实现多态(后序讲)。

1.3:继承的语法

在Java中如果要表示类之间的继承关系,需要借助extends关键字,具体如下:
 

修饰符 class 子类 extends 父类 {
// ...
}

注意:

1. 子类会将父类中的成员变量或者成员方法继承到子类中了
2. 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了

1.4 父类成员访问

在继承体系中,子类将父类中的方法和字段继承下来了,那在子类中能否直接访问父类中继承下来的成员呢?

我先创建了4个类(Dog Cat Test(测试)Animal)
就可以看到在Test类main方法中就可以使用2个子类 一个父类的方法和成员变量
运行:

继承也会出现成员变量用不了:

因为Animal类中的name被private修饰:

修改方案:(将类中属性name改成public 也行 但是不好)
另一种,我们不是创建了getname()方法,就可以直接使用,方法去调用private修饰的成员变量:

如果修饰的成员变量是piblic就可以直接使用name。

1.4.1 子类中访问父类的成员变量

类和父类都出现同一个变量名:
会出现什么情况呢
Dog类:我创建了一个与父类相同的变量,看打印谁。

运行:

第一个红框就是做一个对比;
旺财正在吃骨头 这个都是在父类继承的方法。
然后bark方法我们创建在子类,然后优先使用我们在子类创建的变量name。(就是就近原则)
一般不建议这样,还需要区分变量。

1.4.2 子类中访问父类的成员方法

子类和父类有成员方法相同:

运行:

打印的还是子类的结构。(总结还是优先打印子类的)


【说明】

1通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
2通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法适传递的参数选择合适的方法访问,如果没有则报错;


有时候,确实会出现子类和父类的属性名字相同:是否有办法,显示指定,使用父类的版本?
:可以通过super关键字,指定访问父类的属性

1.5 super关键字

由于设计不好,或者因场景需要,子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成员时,该如何操作?直接访问是无法做到的,Java提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员。

运行:

this 访问子类,super访问父类
(不能在静态使用)

super也可以调用方法(还可以用来调用父类构造方法)

运行:

1.6 子类构造方法

父子父子,先有父再有子,即:子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。

运行:

先打印父类的构造在打印子类
在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执行子类的构造方法,因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整 。

注意:
1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法
2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

1.7 super和this

uper和this都可以在成员方法中用来访问:成员变量和调用其他的成员函数,都可以作为构造方法的第一条语句,那他们之间有什么区别呢?
【相同点】
1. 都是Java中的关键字
2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
【不同点】
     1  this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用
     2. 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
     3在构造方法中:this(...)用于调用本类构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造方法中出现
     4构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)用户不写则没有

1.8 protected 关键字(就是与privat和public并列关系)

在类和对象章节中,为了实现封装特性,Java中引入了访问限定符,主要限定:类或者类中成员能否在类外或者其他包中被访问。

使用范围:

1.8.1:default使用

运行结果:

Test和Test2在同一个包,但是Test3是在另外一个包
因为x是default级别,在其他包的类中无法访问

1.8.2:protected的实际应用

介绍protected:protected这个界别要比刚才谈到的default级别更低一些
有更多的类可以访问。

运行:Test4

运行:Test3

Test4使用继承Test,然后我们就可以使用y,但x不可以,因为x是default属性,不可以在其他包中使用,由此可以protect的范围比default更广,protected可以使变量在其他包(子类)也可以使用。

说一下实际情况:实际开发中,绝大部分情况,都是private和public,甚至有的编程语言,压根没有protected这种权限级别,

1.9继承方式

考虑的是类多了,才会考虑。
但在Java中只支持以下几种继承方式:

多层继承,语法上允许,但是实际开发的时候,如果继承层次太多,影响代码可读性,实际当中4-5就差不多了。

多继承就不行(好像脚踏两只船)所以我们java禁止这种继承


注意:Java中不支持多继承。

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

1.10:final关键字

1:使用final修饰关键字,改变了不能被修改。

final关键可以用来修饰变量、成员方法以及类。
eg:先找个例子
 

`package object2.finaltest;`  
`public class Test {`  
    `final int x=10;`  
    `public static void main(String[] args) {`  
         `int x=10;`  
        `System.out.println(x);`  
         `x=20;`  
        `System.out.println(x);`  
    `}`  
`}`

运行结果:

接下来就是final的操作了:

看到第二个x变量直接爆红

爆错原因为无法为最终变量x分配值,因为第一个x已经被final修饰了,(功能就是固定变量的值,无法修改)
还有个eg:

2:使用final修饰类(此时该类就不能被继承)

该类就不能被Test1继承

1.11:继承和组合

和继承类似 , 组合也是一种表达类之间关系的方式 , 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法
( 诸如 extends 这样的关键字 ), 仅仅是将一个类的实例作为另外一个类的字段。
继承表示对象之间是 is-a 的关系 ,比如:狗是动物,猫是动物
组合表示对象之间是 has-a 的关系 ,比如:汽车
汽车和其轮胎、发动机、方向盘、车载系统等的关系就应该是组合,因为汽车是有这些部件组成的。

  这就是组合,每一个部分拼凑成猫。

组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择,一般建议:能用组合尽量用组合。

二:总结

本文系统介绍了Java中的继承机制。继承通过extends关键字实现,允许子类复用父类的属性和方法,达到代码复用目的。文中详细讲解了继承的语法、super关键字的使用、父类成员访问规则、子类构造方法调用顺序等核心概念。同时比较了super和this的区别,介绍了protected关键字的作用范围。文章还指出Java不支持多继承,建议继承层次不超过3-5层,并介绍了final关键字限制继承的特性。最后对比了继承与组合的关系,指出组合表示has-a关系而继承表示is-a关系,建议优先使用组合。继承是面向对象编程实现代码复用和多态的重要机制。

更多推荐