当前位置: 首页 > news >正文

面向对象进阶--继承(Java继承(超详解))

目录

1. 继承

1.1 继承概述

1.2 继承特点

1.3练习

1.4继承父类的内容

构造方法是否被子类继承

成员变量是否被子类继承

成员方法是否被子类继承

1.5总结

继承中:成员变量的访问特点

继承中:成员方法的访问特点

方法重写概述

方法重写的本质

继承中:构造方法的特点

this,super使用总结


1. 继承

1.1 继承概述

继承是面向对象的三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。

继承是指在原有类的基础上,进行功能扩展,创建新的类型。

继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
JAVA中类只有单继承,没有多继承!
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
子类和父类之间,从意义上讲应该具有"is a"的关系。
extends的意思是“扩展”,子类是父类的扩展。

继承的格式:

  • 格式: public class 子类名 extends 父类名{}
  • 例如: public class Zi extends Fu {}
  • Fu:是父类,也被称为基类、超类
  • Zi: 是子类,也被称为派生类

继承中子类的特点:

子类可以有父类的内容,子类还可以有自己特有的内容

1.2 继承特点

Object类是所有子类的父类 如果你没有写父类 默认父类就是Object类

1.3练习

如果父类加了private私有关键字 ,子类就不能使用父类的特性了

测试类

package comitheima.a01oopextendsdemo01;public class Test {public static void main(String[] args) {//1.创建布偶猫对象Ragdoll r1 = new Ragdoll();r1.eat();r1.drink();r1.catchMouse();System.out.println("----------------");//2.创建哈士奇对象Husky h=new Husky();h.eat();h.drink();h.DownHome();}}

package comitheima.a01oopextendsdemo01;public class animal {public  void eat(){System.out.println("吃饭");}public  void drink (){System.out.println("喝水");}
}
package comitheima.a01oopextendsdemo01;public class cat extends  animal {public void catchMouse(){System.out.println("猫在抓老鼠");}
}
package comitheima.a01oopextendsdemo01;public class dog extends  animal {public void watchhose(){System.out.println("狗在看家");}
}
package comitheima.a01oopextendsdemo01;public class Husky extends dog {public void DownHome(){System.out.println("哈士奇拆家");}}

package comitheima.a01oopextendsdemo01;public class LiHua extends cat {
}
package comitheima.a01oopextendsdemo01;public class Ragdoll extends cat {}
package comitheima.a01oopextendsdemo01;public class Teddy extends dog {public void touch(){System.out.println("泰迪蹭一蹭");}
}

1.4继承父类的内容

构造方法是否被子类继承

构造方法的类名和子类的类名不一样,违背了构造方法的特征,所以父类的构造方法不能被子类继承

package comitheima.a01oopextendsdemo02;public class Test {public static void main(String[] args) {Zi zi = new Zi();//Zi zi1 = new Zi("zhasa",18);}
}class  Fu{String name;int age;public Fu(String name, int age) {this.name = name;this.age = age;}public Fu(){}
}
class Zi extends Fu{//如果一个类没有构造方法,虚拟机会自动给你添加一个默认的空参的构造方法
}

说明了子类没有继承父类的构造方法,空参构造也是虚拟机给的

成员变量是否被子类继承

public修饰的成员变量

对象先找子类再找父类

private修饰的成员变量

private修饰的变量 子类调用不了变量只能继承不能直接使用

成员方法是否被子类继承

只有非static修饰 非private修饰非final修饰的方法是虚方法
虚方法就可以继承给子类,子类就会加载方法,每次子类调用方法的时候就可以从自己的虚方法里面去调用

1.5总结

1.构造方法的类名和子类的类名不一样,违背了构造方法的特征,所以父类的构造方法不能被子类继承,不管是public修饰还是private修饰都不能被子类继承
2.成员变量不管是private修饰还是public修饰都能继承 ,但是private修饰的成员变量只能继承不能直接调用
3. 只有public修饰的成员方法才能继承,private修饰的成员方法不能继承
4.只有非static修饰 非private修饰非final修饰的方法是虚方法
虚方法就可以继承给子类,子类就会加载方法,每次子类调用方法的时候就可以从自己的虚方法里面去调用
 

继承中:成员变量的访问特点

遵循就近原则

在子类方法中访问一个变量

最先在子类局部范围找,如果没有就在子类成员范围找,最后在父类成员范围找,如果都没有就报错(不考虑父亲的父亲...)。

name先在局部位置找,然后再到本类的成员位置找,然后在到父类找,一级一级往上找

this访问的是本类的成员变量 ,super是访问父类的成员变量

 例如:创建一个父类Fu

public class Fu {public int age = 10;
}

创建一个子类Z

public class Zi extends Fu {public int heigth = 180;public int age = 20;// 若果没有这句,和下面那句,输入的是10public void show() {int age = 30;// 若果没有这句,输入的是20System.out.println(age);System.out.println(heigth);}
}

创建一个测试类Test

public class Test {public static void main(String[] args) {// 创建对象调用方法Zi z = new Zi();z.show();}
}

结果:

继承中:成员方法的访问特点

通过子类对象访问一个方法:

先子类成员范围找,如果找不到就在父类成员范围找,如果都没有就报错(不考虑父亲的父亲...)


 

方法重写概述

方法重写概述:子类中出现了和父类中一模一样的方法声明
方法重写的应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容

@Override
是一个注解可以帮助我们检查重写方法的方法声明的正确性

方法重写的本质

只有被添加到虚方法中的方法才能被重写

package comitheima.a01oopextendsdemo04;import java.util.SimpleTimeZone;public class Dog {public void eat() {System.out.println("狗在吃狗粮");}public void drink(){System.out.println("狗在喝水");}public void lookhome(){System.out.println("狗在看家");}
}
package comitheima.a01oopextendsdemo04;public class Husky extends  Dog {public void downhome(){System.out.println("哈士奇在拆家");}
}
package comitheima.a01oopextendsdemo04;public class Chinesedog extends  Dog {public void eat(){//父类的方法不能满足我们的需求,所以进行了重写,且父类的方法我根本用不到System.out.println("中化田园犬在吃剩饭");}
}
package comitheima.a01oopextendsdemo04;public class sharper extends Dog {//因为沙皮狗吃的是狗粮和骨头//父类的方法不能满足我们的需求,所以进行了重写//方法重写@Overridepublic void eat(){super.eat();System.out.println("沙皮狗在吃骨头");}
}
package comitheima.a01oopextendsdemo04;public class Test {public static void main(String[] args) {Husky h= new Husky();h.eat();h.drink();h.lookhome();h.downhome();System.out.println("----------");sharper sh=new sharper();sh.eat();sh.drink();sh.lookhome();System.out.println("----------");Chinesedog Ch=new Chinesedog();Ch.eat();Ch.drink();Ch.lookhome();}

继承中:构造方法的特点

子类中所有的构造方法默认都会访问父类中无参的构造方法。

  1. 因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
  2. 每一个子类构造方法的第一条语句默认都是: super()

 例如:创建一个父类Fu

public class Fu {public Fu() {System.out.println("Fu中无参构造方法被调用");}public Fu(int age) {System.out.println("Fu中带参构造方法被调用");}
}

创建一个子类Zi

 
public class Zi extends Fu {public Zi() {// super();System.out.println("Zi中无参构造方法被调用");}public Zi(int age) {// super();System.out.println("Zi中带参构造方法被调用");}
}

测试:Test

public class Test {public static void main(String[] args) {Zi z = new Zi();System.out.println("-------------------");Zi zi = new Zi(18);}
}

子类的初始化之前,要调用父类的构造方法先完成父类的数据初始化
如果想要调用父类的有参构造 ,必须手动加上super.
我还想强调的是父类的构造方法,子类是不能继承,但是子类可以去调用父类的方法,继承不了不代表调用不了,不管是private修饰还是public修饰的构造方法,子类都继承不了父类的构造方法

 如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?

  1. 通过使用super关键字去显示的调用父类的带参构造方法
  2. 在父类中自己提供一个无参构造方法
  3. 推荐: 自己给出无参构造方法

例如:创建一个父类Fu

public class Fu {// public Fu() {// System.out.println("Fu中无参构造方法被调用");// }public Fu(int age) {System.out.println("Fu中带参构造方法被调用");}
}

创建一个子类Zi

public class Zi extends Fu {public Zi() {super(18);System.out.println("Zi中无参构造方法被调用");}public Zi(int age) {super(18);System.out.println("Zi中带参构造方法被调用");}
}

测试:Test

public class Test {public static void main(String[] args) {Zi z = new Zi();System.out.println("-------------------");Zi zi = new Zi(18);}
}

super访问父类的构造方法

package comitheima.a05oopextendsdemo05;public class Student  extends  Person{public  Student(){//子类构造方法中隐藏的super()去访问父类的无参构造super();System.out.println("子类的无参构造");}public  Student(String name,int age){//子类构造方法中手动去在super方法中传参数 就可以去调用带参构造super(name,age);System.out.println("子类的无参构造");}
}

package comitheima.a05oopextendsdemo05;public class Test {public static void main(String[] args) {Student s1 = new Student("zhangsa",18);System.out.println(s1.name+" "+s1.age);}
}
package comitheima.a05oopextendsdemo05;public class Person {String name;int age;public Person() {System.out.println("父类的无参构造");}public Person(String name, int age) {this.name = name;this.age = age;}
}

      


this,super使用总结

例如:定义一个父类Fu

public class Fu {public int age = 10;}

定义一个子类Zi

 
public class Zi extends Fu {public int age = 20;public void show() {int age = 30;System.out.println(age); // 30// 访问本类中的成员变量ageSystem.out.println(this.age);// 访问Fu类中的成员变量ageSystem.out.println(super.age);}
}

测试:Test

public class Test {public static void main(String[] args) {Zi z = new Zi();z.show();}
}

this访问本类的构造方法

测试类

package comitheima.a06oopextendsdemo06;import com.sun.tools.javac.Main;public class Test {public static void main(String[] args) {Manager m=new Manager("001","zhangsan",6666,1000.0);System.out.println(m.getId()+" "+m.getName()+" "+m.getSalary()+" "+m.getBonus());m.word();m.eat();System.out.println("--------------");Cook c=new Cook("002","lisi",1111);System.out.println( c.getId()+" "+c.getName()+" "+c.getSalary());c.word();c.eat();}
}

父类

public class Employee {private String id;private String name;private int salary;public Employee() {}public Employee(String id, String name, int salary) {this.id = id;this.name = name;this.salary = salary;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getSalary() {return salary;}public void setSalary(int salary) {this.salary = salary;}public void word(){System.out.println("员工在工作");}public void eat(){System.out.println("在吃米饭");}
}

子类经理类

public class Manager extends Employee {private double bonus;public Manager() {}//带全部的构造方法//父类+子类的构造方法public Manager(String id, String name, int salary, double bonus) {super(id, name, salary);//调用父类的有参构造,把id,name,salary,bonus的值给父类this.bonus = bonus;//子类的特有的奖金在本类赋值}public double getBonus() {return bonus;}public void setBonus(double bonus) {this.bonus = bonus;}@Overridepublic void word() {System.out.println("经理在管理其他人");}}

子类厨师类

package comitheima.a06oopextendsdemo06;public class Cook extends  Employee {public Cook() {}public Cook(String id, String name, int salary) {super(id, name, salary);}@Overridepublic void word() {System.out.println("厨师在炒菜");}
}

相关文章:

  • 关于QTcreator,19年大学时写的文章了,之前写在印象笔记现在拉过来,往事如烟呐
  • C#面:详细阐述什么是 DTO
  • 什么是数字化,什么是数智化?数字化与数智化的区别和联系
  • BT音频方案
  • 央国企财务专家的“专家课”——中国总会计师协会联合实在智能举办RPA专项培训
  • web标准与浏览器前缀
  • GANs网络在图像和视频技术中的应用前景
  • springboot中maven的使用教程
  • Qt 实战(4)信号与槽 | 4.1、信号与槽机制
  • 切换到root用户的方法和区别
  • Linux 编写脚本自动清理旧的日志文件,释放磁盘空间
  • 图论之岛屿系列
  • QGraphicsItem 自定义是否被选中
  • 人体接近传感器,ATM微波传感器,人体存在传感器 微波探测器YTMW8631
  • Python办公自动化—pandas读取Excel进行插入列、修改列的类型,apply函数与字典结合匹配等操作+完整代码
  • HTTP--网络协议分层,http历史(二)
  • JavaScript设计模式与开发实践系列之策略模式
  • Java多线程(4):使用线程池执行定时任务
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • SQLServer之创建显式事务
  • WebSocket使用
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 基于axios的vue插件,让http请求更简单
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 深入 Nginx 之配置篇
  • 使用putty远程连接linux
  • 线上 python http server profile 实践
  • ionic入门之数据绑定显示-1
  • 湖北分布式智能数据采集方法有哪些?
  • ​flutter 代码混淆
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • # Redis 入门到精通(一)数据类型(4)
  • #{}和${}的区别是什么 -- java面试
  • $jQuery 重写Alert样式方法
  • (1)(1.11) SiK Radio v2(一)
  • (4)STL算法之比较
  • (done) 两个矩阵 “相似” 是什么意思?
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (四)图像的%2线性拉伸
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)一些感悟
  • *Django中的Ajax 纯js的书写样式1
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET C# 配置 Options
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .NET MVC之AOP
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • :not(:first-child)和:not(:last-child)的用法
  • @Bean, @Component, @Configuration简析
  • @RequestMapping 和 @GetMapping等子注解的区别及其用法
  • @基于大模型的旅游路线推荐方案