Java语法之继承(上)

简介: 上次给大家分享了Java的封装,今天小编给大家分享面向对象三大特性的第二大特性,也就是继承,fighting~~

🎉一. 继承的概念


1.1 为什么需要继承

生活中的继承:

6ac51074c70dcef6505d00fd33f421e1.jpeg

兔子和羊属于食草动物类,狮子和豹属于食肉动物类。

食草动物和食肉动物又是属于动物类。

所以继承需要符合的关系是:is-a,父类更通用,子类更具体。

虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。


为了方便大家理解,我们举个例子,我们定义一个猫和够,他们都有自己的名字和年龄,这是他们所共有的,但是他们表现出不同的行为,比如狗会汪汪叫,猫会喵喵叫,我们就可以把他们共有的特性抽取出去,写成一个父类,看代码:

3ee8e66b423c4c518f97e71cd59036df.png

既然大家有着同样的属性和方法,我们就可以这样改写:

image.png

么,这里继承的概念就出来了,没错,这就是继承!从这里不难看出,继承实际上就是用来对共性的抽取,实现对代码的复用!



1.2 继承的概念

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类,继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。


继承的格式:

在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:

class父类 {
}
class子类extends父类 {
}

1.3继承的语法

语法1.2中就给大家介绍完了,我们这里看一下具体的实现吧,代码:

classAnimal {
publicStringname;
publicintage;
publicvoidageShow() {
System.out.println(name+"今年"+age+"岁了");
    }
}
classDogextendsAnimal {
publicvoidwangwang() {
System.out.println(name+"汪汪叫!");
    }
}
classCatextendsAnimal {
publicvoidmiaomiao() {
System.out.println(name+"喵喵叫!");
    }
}
publicclassTest_2 {
publicstaticvoidmain(String[] args) {
Dogdog=newDog();// dog类中并没有定义任何成员变量,name和agedog.name="旺财";
dog.age=3;
dog.ageShow();
Catcat=newCat();
cat.name="咪咪";
cat.age=5;
cat.ageShow();
    }
}

运行结果:

e21bb65e4b4144f8bffb2c35dfae13f5.png

注意:

1. 子类会将父类中的成员变量或者成员方法继承到子类中了

2. 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了


1.4 父类成员的访问

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

1)子类和父类不存在同名成员变量

classDemo {
publicinta=1;
publicintb=2;
publicintc=3;
}
classBaseextendsDemo {
publicvoidfunc() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
    }
}
publicclassTest_3 {
publicstaticvoidmain(String[] args) {
Basebase=newBase();
base.func();
    }
}

55c431ba240f422099bb1229e23d80ce.png

2)子类和父类成员变量同名

classDemo {
publicinta=1;
publicintb=2;
publicintc=3;
}
classBaseextendsDemo {
inta=10;
intb=20;
publicvoidfunc() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
    }
}
publicclassTest_3 {
publicstaticvoidmain(String[] args) {
Basebase=newBase();
base.func();
    }
}

063b11dc076345bba58f12480e0fbe53.png

从上面俩个例子我们可以得出:

如果访问的成员变量子类中有,优先访问自己的成员变量。

如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。

如果访问的成员变量与父类中成员变量同名,则优先访问自己的。


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

1)当子类和父类中成员方法名字不同

classDemo {
publicvoidBasefun1() {
System.out.println("父类");
    }
}
classBaseextendsDemo {
publicvoidBasefun() {
System.out.println("子类");
    }
publicvoidfunc() {
Basefun();
Basefun1();
    }
}
publicclassTest_3 {
publicstaticvoidmain(String[] args) {
Basebase=newBase();
base.func();
    }
}

这里也不难看出,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。

2)当子类和父类中成员方法名字相同

classDemo {
publicvoidBasefun() {
System.out.println("父类");
    }
}
classBaseextendsDemo {
publicvoidBasefun() {
System.out.println("子类");//优先调用子类自己的方法    }
publicvoidfunc() {
Basefun();
    }
}
publicclassTest_3 {
publicstaticvoidmain(String[] args) {
Basebase=newBase();
base.func();
    }
}

3326fa5b2d0a41df822bb65956618c3e.png

从输出结果我们可以出,通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。


1.5 子类构造方法

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。我们也可通过构造方法给父类中的成员变量赋值:

classAnimal {
publicStringname;
publicintage;
publicAnimal(Stringname, intage) {    //构造方法this.name=name;
this.age=age;
    }
publicvoidageShow() {
System.out.println(name+"今年"+age+"岁了");
    }
}
classDogextendsAnimal {
publicvoidwangwang() {
System.out.println(name+"汪汪叫!");
    }
publicDog(Stringname,intage){
super(name, age);
    }
}
classCatextendsAnimal {
publicvoidmiaomiao() {
System.out.println(name+"喵喵叫!");
    }
publicCat(Stringname,intage){
super(name, age);
    }
}
publicclassTest_2 {
publicstaticvoidmain(String[] args) {
Dogdog=newDog("旺财",3);
dog.ageShow();
dog.wangwang();
Catcat=newCat("咪咪",5);
cat.ageShow();
cat.miaomiao();
    }
}

d6c49ecbca8641bcb9b305924a4903bd.png

注意:

1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法

2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。

3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。

4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现


🎉二. 继承的关键字


2.1 super和this关键字

1)super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

2)this关键字:指向自己的引用。

举个例子,这里我们主要介绍super:

classTest1 {
publicinta=1;
publicintb=2;
}
classTest2extendsTest1 {
publicinta=10;
publicintb=20;
voidfun() {
System.out.println(a);
System.out.println(super.b);
    }
}
publicclassTest_3 {
publicstaticvoidmain(String[] args) {
Test2test2=newTest2();
test2.fun();
    }

如果这里我们要通过子类去访问父类中的成员,就需要在成员变量前面加上super关键字,这里我们就可以访问到上述代码中父类b的值了!


2.2 final关键字

final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。

final 含义为 "最终的"。

使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:

publicclassTest_4 {
finalinta=10;
a=20;//被final修饰的变量是被密封的,不允许修改的}
classone {
}
finalclasstowextendsone {
}
classthreeextendstow{   //被final修饰的类是不能被继承的,属于密封类}

目录
相关文章
|
12天前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
本系列教程笔记详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。若需快速学习Kotlin,建议查看“简洁”系列教程。本期重点介绍了Kotlin与Java的共存方式,包括属性、单例对象、默认参数方法、包方法、扩展方法以及内部类和成员的互操作性。通过这些内容,帮助你在项目中更好地结合使用这两种语言。
26 1
|
13天前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
25 2
|
11天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
12 3
|
11天前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
24 2
|
11天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
23 2
|
11天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
22 1
|
12天前
|
Java 编译器 Android开发
Kotlin语法笔记(28) -Kotlin 与 Java 混编
本系列教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速学习Kotlin的用户,推荐查看“简洁”系列教程。本文档重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android library开发建议以及在Kotlin和Java之间互相调用的方法。
13 1
|
12天前
|
安全 Java 编译器
Kotlin语法笔记(27) -Kotlin 与 Java 共存(二)
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。若需快速入门,建议查阅“简洁”系列教程。本文重点探讨Kotlin与Java共存的高级话题,包括属性访问、空安全、泛型处理、同步机制及SAM转换等,助你在项目中逐步引入Kotlin。
13 1
|
13天前
|
Java 编译器 Android开发
Kotlin语法笔记(28) -Kotlin 与 Java 混编
Kotlin语法笔记(28) -Kotlin 与 Java 混编
17 2
|
18天前
|
Java 程序员 编译器
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。本文通过示例详细解析了保留字的定义、作用及与自定义标识符的区别,帮助开发者避免因误用保留字而导致的编译错误,确保代码的正确性和可读性。
38 3