java的继承(extends)

java的继承(extends)当多个类存在相同的属性 变量 和方法时 可以从这些类中抽象出父类 在父类中定义这些相同的属性和方法 只需要通过 extends 来声明继承父类即可继承示意图

大家好,欢迎来到IT知识分享网。

一、为什么需要继承

我们编写了两个类,一个是Pupil类(小学生),还有一个是 Graduate(大学毕业生),发现两个类的属性和方法 有很多是相同的,于是便引出了  继承 可以减轻代码的冗余,提升代码的复用性

把多个类共有的方法提取到父类中去,多个类继承父类,可以直接使用父类中的方法

个人理解 类就是模板,父类就是模板的模板

二、继承基本介绍

当多个类存在相同的属性[变量]和方法时,可以从这些类中抽象出 父类,在父类中定义这些相同的属性和方法,只需要通过  extends 来  声明继承父类即可

继承示意图

java的继承(extends)

三、继承的基本语法

class 子类 extends 父类{

}

1、子类会自动拥有父类定义的属性和方法

2、父类又叫  超类、 基类、

3、子类又叫派生类

四、快速入门案例

父类  Student  共有属性方法

package com.lmdedu.extend_.improve; //父类,是Pupil和Graduate的父类 public class Student { //共有属性 public String name; public int age; private double score; //共有方法 public void setScore(double score) { this.score = score; } public void showInfo(){ System.out.println("学生名" + name + "年龄" + age + "成绩" + score); } }

Pupil 和 Graduate  写特有属性和方法   并继承  父类Student的   属性方法

package com.lmdedu.extend_.improve; //extends Student继承父类Student public class Pupil extends Student { //写独特属性和方法 public void testing(){ System.out.println("小学生" + name + "正在考小学数学.."); } }
package com.lmdedu.extend_.improve; //extends Student继承父类Student public class Graduate extends Student{ public void testing(){ System.out.println("大学生" + name + "正在考大学数学.."); } } 

五、继承的细节和注意事项

1、子类 继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性不能在子类 直接访问,要通过父类提供的公共的方法去访问

父类 Base

package com.lmdedu.extend_; public class Base {//父类 public int n1 = 100; protected int n2 = 200; int n3 = 300; private int n4 = 400; public Base(){//无参构造器 System.out.println("base()...."); } //在父类提供一个public的方法 获取私有的 属性 public int getN4(){ return n4; } public void test100(){ System.out.println("test100"); } protected void test200(){ System.out.println("test200"); } void test300(){ System.out.println("test300"); } private void test400(){ System.out.println("test400"); } //为了调用私有化 方法 test400,提供一个public方法 public void callTest400(){ test400(); } }

子类  Sub 

package com.lmdedu.extend_; public class Sub extends Base{//子类Sub继承父类 Base public Sub(){//无参构造器 System.out.println("Sub()....."); } public void sayOk(){ //我们发现父类的 非private属性和方法 均可以调用 //属性 System.out.println(n1); System.out.println(n2); System.out.println(n3); //方法 test100(); test200(); test300(); //但是私有属性不能在子类 直接访问,要通过父类提供的公共的方法去访问 System.out.println("n4 =" + getN4()); callTest400(); } }

main主函数

package com.lmdedu.extend_; public class ExtendsDetail { public static void main(String[] args) { Sub sub = new Sub(); sub.sayOk(); } }

2、子类必须调用父类的构造器,完成父类的初始化

父类构造器

 public Base(){//无参构造器 System.out.println("base()...."); }

子类构造器

 public Sub(){//无参构造器 System.out.println("Sub()....."); }

可以看出  base()…先输出,说明  先进行  父类构造器的初始化,再完成子类构造器的初始化

 java的继承(extends)

3、当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器

     若父类没有提供无参构造器,必须在子类的构造器中使用  super  去指定使用   父类的哪个构造       器完成父类的初始化,否则编译不通过

父类中未提供无参构造器 ,在子类的构造器中使用super进行指定父类的构造器

子类构造器 如下

 public Sub(){//无参构造器 //默认调用父类的无参构造器,当父类没有无参构造器时,进行指定 super("lmd",20); System.out.println("Sub()....."); }

4、若希望指定调用 父类的 某个构造器  需要显式的调用一下   super(参数列表);

5、super在使用时,必须放在构造器的第一行   (super只能在构造器中使用)

6、super() 和 this()  都只能放在构造器的第一行,因此不能共存在 一个构造器中(this()是在构造器中调用构造器)

7、java所有的类都是Object的子类(快捷键ctrl + h可以看到所有类的继承关系)

java的继承(extends)

8、父类构造器的调用不限于直接父类!将一直向上追溯到Object类(顶级父类)

java的继承(extends)

让Base继承 TopBase 

TopBase 构造器

 public TopBase(){ System.out.println("TopBase()构造器被调用"); }

所以会输出

java的继承(extends)

9、子类 最多只能 直接继承 一个父类,java中是单继承机制

     思考如何 让A类 继承B类和 C类  

     可以让A继承B,B继承C

java的继承(extends)

10、不能滥用继承,  子类和父类之间必须满足 is-a 关系

Person is a Music?

Person  Music

Music extends Person//不合理

Animal

Cat extends Animal //合理

六、继承本质详解

下面将通过一个案例分析,当子类继承父类,创建子类对象时,内存中到底发生了什么

结论:当子类对象创建好后,建立 查找的关系

package com.lmdedu.extend_; / *讲解继承的本质 */ public class ExtendsTheory { public static void main(String[] args) { Son son = new Son();//内存的布局 } } class Grandpa{//爷爷类 String name = "大头爷爷"; String hobby = "旅游"; } class Father extends Grandpa{//父类 String name = "大头爸爸"; int age = 39; } class Son extends Father{//子类 String name = "大头儿子"; }

分析创建子类对象时,内存中到底发生了什么

Son son = new Son();

1、先加载Object类信息,再加载Grandpa类,再加载父类Father,再加载Son类信息

java的继承(extends)

2、在堆中分配一个地址空间  给 对象son

java的继承(extends)

3、地址空间中 有哪些属性

java的继承(extends)

4、将内存空间地址 传给 对象son

java的继承(extends)

属性的访问规则

public class ExtendsTheory { public static void main(String[] args) { Son son = new Son();//内存的布局 //看看会输出 哪个 name, //按照查找规则返回数据 //1)首先看子类是否有该属性, //2)若子类有这个属性,并且可以访问,则返回信息 //3)若子类没有这个属性,就看父类有没有这个属性(若父类有这个属性,并且可以访问,则返回信息) //4)若父类没有这个属性,按照3)的规则,继续向上找 System.out.println(son.name);//输出 子类的name属性 大头儿子 System.out.println(son.age);//输出 父类的age属性 39 System.out.println(son.hobby);//输出 爷爷类的 hobby属性 旅游 } }

思考若将 Father类中的 age属性改为private,则在对象son的存储空间中,是否还有age这个属性?

private int age = 39;

答案是  仍然有  ,只需让 Father 类提供一个公有的访问方法  就能用

思考 若在 Grandpa类中 添加 public age属性,然后将Father类中的  age属性 改为private,直接访问age时是否会跳过  Father类的private age属性,访问Grandpa类中 的 public age属性?

答案是  不会,  只要在查找过程中 ,被挡住了 不会跳过去 向上找

七、课堂练习

java的继承(extends)

注意:有this 就没有super

输出答案

a

b name

b

java的继承(extends)

输出

我是A类

name+”我是B类的有参构造”

”我是C类的有参构造“

”我是C类的无参构造“

java的继承(extends)

package com.lmdedu.extend_; //测试类 class Test{ //主方法 public static void main(String[] args) { Pc pc = new Pc("i9","16G","1T","惠普"); System.out.println(pc.getPcDetail()); NotePad notePad = new NotePad("i9","16G","1T","black"); System.out.println(notePad.getNotePadDetail()); } } //父类Computer class Computer{ private String cpu; private String memory; private String hardDisk; public Computer(String cpu, String memory, String hardDisk) { this.cpu = cpu; this.memory = memory; this.hardDisk = hardDisk; } public String getCpu() { return cpu; } public void setCpu(String cpu) { this.cpu = cpu; } public String getMemory() { return memory; } public void setMemory(String memory) { this.memory = memory; } public String getHardDisk() { return hardDisk; } public void setHardDisk(String hardDisk) { this.hardDisk = hardDisk; } public String getDetail(){ return "cpu为" + cpu +"内存为" + memory + "硬盘为" + hardDisk; } } //子类Pc class Pc extends Computer{ String brand; //这里也体现出:继承设计的基本思想 //父类的构造器完成 父类属性初始化 //子类的构造器完成 子类属性初始化 public Pc(String cpu, String memory, String hardDisk, String brand) { super(cpu, memory, hardDisk); this.brand = brand; } public String getPcDetail(){ return getDetail() + "品牌为" + brand; } } class NotePad extends Computer{ String color; public NotePad(String cpu, String memory, String hardDisk, String color) { super(cpu, memory, hardDisk); this.color = color; } //打印信息 public String getNotePadDetail(){ return getDetail() + "颜色为" + color; } } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/148771.html

(0)
上一篇 2025-03-28 18:10
下一篇 2025-03-28 18:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信