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

Java零基础笔记08(Java编程核心:面向对象编程高级 {继承、多态})

1.继承

         Java中提供了一个关键字extends,用这个关键字,可以让一个类和另一个类建立起父子关系。

子类能继承啥?

● 子类能继承父类的非私有成员(成员变量、成员方法) 继承后对象的创建

● 子类的对象是由子类、父类共同完成的。 

注意: 

        子类对象其实是由子类和父类多张设计图共同创建出来的对象,所以子类对象是完整的

1.1  权限修饰符

        就是用来限制类中的成员 ( 成员变量,  成员方法,  构造器 ) 能够被访问的范围

修饰符		同类	同包		不同包的子类	不同包的非子类	通俗解释
public		✅		✅			✅			✅				完全开放,像公共广场
protected	✅		✅			✅			❌				家族共享,像家族遗产
默认		✅		✅			❌			❌				小区内部,像小区公共设施
private		✅		❌			❌			❌				完全私有,像自家卧室

1.2  继承的特点

1.2.1  单继承和多层继承

public class Test {public static void main(String[] args) {// 目标:继承的注意事项:继承的特点。}
}// 1. java的类只能是单继承的,不支持多继承,支持多层继承
class A {
}class B extends A {
}class C extends B {
}

为什么Java不支持多继承

1.2.2  Java中的祖宗类:Object

● Java中所有类,要么直接继承了Object,要么默认继承了Object,要么间接继承Object。

● 因此,Object是所有类的祖宗类。

1.2.3  继承后子类访问成员的特点:  就近原则

  1. 在子类方法中访问其他成员(成员变量、成员方法),是依照就近原则的。先子类局部范围找,然后子类成员范围找,然后父类成员范围找,如果父类范围还没有找到则报错。

  2. 如果子父类中,出现了重名的成员,会优先使用子类的,如果此时一定要在子类中使用父类的怎么办?可以通过super关键字,指定访问父类的成员:

// 定义父类 Fu
class Fu {// 定义一个字符串属性 name,并初始化为 "fu的name"String name = "fu的name";// 定义一个方法 run,并打印 "fu类的run方法"public void run() {System.out.println("fu类的run方法");}
}// 定义子类 Zi,继承自父类 Fu
class Zi extends Fu {// 定义一个字符串属性 name,并初始化为 "zi的name"String name = "zi的name";// 定义一个方法 show,展示 name 属性的访问特点public void show() {// 定义一个局部变量 name,并初始化为 "show的name"String name = "show的name";// 打印局部变量 name 的值System.out.println(name); // 输出: show的name// 打印当前对象的 name 属性的值,由于就近原则,输出 Zi 类的 nameSystem.out.println(this.name); // 输出: zi的name// 打印父类的 name 属性的值System.out.println(super.name); // 输出: fu的name}// 重写父类的 run 方法,并打印 "zi类的run方法"public void run() {System.out.println("zi类的run方法");}
}// 定义主类 Test2,包含 main 方法
public class Test2 {public static void main(String[] args) {// 创建 Zi 类的对象 ziZi zi = new Zi();// 调用 Zi 类的 show 方法zi.show();// 调用 Zi 类的 run 方法zi.run(); // 输出: zi类的run方法// 调用父类的 run 方法zi.super.run(); // 输出: fu类的run方法}
}

1.2.4  方法重写

        当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。

重写规范:  声明不变,  重新实现

public class Test {public static void main(String[] args) {// 目标:认识方法重写,再搞清楚场景。Cat cat = new Cat();cat.cry();}
}class Cat extends Animal {// 方法重写:方法名称、形参列表必须一样,这个方法就是方法重写。@Override // 方法重写的校验注解(标志),要求方法名称和形参列表必须与被重写方法一致,否则报错!更安全,可读性好,更优雅!public void cry() {System.out.println("🐱 喵喵喵的叫~~~");}
}class Animal {public void cry() {System.out.println("动物会叫~~~");}
}

方法重写在开发中常见的应用场景:

        子类重写Object类的toString()方法,  以便返回对象的内容

public class Test2 {public static void main(String[] args) {// 目标:方法重写的常见应用场景,子类重写Object的toString方法,以便返回对象的内容。Student s = new Student("赵敏", '女', 25);// System.out.println(s.toString()); // com.itheima.extends5override.Student@b4c966a 所谓的地址System.out.println(s); // com.itheima.extends5override.Student@b4c966a 所谓的地址// 注意1:直接输出对象,默认会调用Object的toString方法(可以省略不写调用toString的代码),返回对象的地址信息// 注意2:输出对象的地址实际上总是没有什么意义的,开发中更希望输出对象的内容信息,所以子类需要重写Object的toString方法。// 以便以后输出对象时,默认调用的是子类重写的toString方法返回对象的内容。}
}class Student {private String name;private char sex;private int age;@Overridepublic String toString() {return "Student{name='" + name + "',sex='" + sex + "',age=" + age + "}";}
}

1.2.5  子类构造器

        子类的全部构造器, 都会先调用父类的构造器, 再执行自己

public static void main(String[] args) {// 目标:认识子类构造器的特点,再看应用场景。// 子类构造器都会先调用父类的无参数构造器,再执行自己的构造器。Zi z = new Zi();
}class Zi extends Fu {public Zi() {System.out.println("子类无参构造器执行了");}
}class Fu {public Fu() {System.out.println("父类无参构造器执行了");}
}


// 父类
// 继承的好处:1.代码复用 2.减少了重复代码。public class People {private String name;private char sex;public People() {}public People(String name, char sex) {this.name = name;this.sex = sex;}public String getName() { return name; }public void setName(String name) { this.name = name; }public char getSex() { return sex; }public void setSex(char sex) { this.sex = sex; }
}// 子类
public class Teacher extends People {private String skill; // 技术。public Teacher(String name, String skill, char sex) {// 子类构造器调用父类构造器的应用场景。// 可以把子类继承自父类这部分的数据也完成初始化赋值。super(name, sex);this.skill = skill;}public String getSkill() {return skill;}
}public class Test2 {public static void main(String[] args) {// 目标:子类构造器调用父类构造器的应用场景。Teacher t = new Teacher( name: "dei", skill: "java、大数据、微服务", sex: 'M');System.out.println(t.getName());System.out.println(t.getSkill());System.out.println(t.getSex());}
}

1.2.6 this (...) 调用兄弟构造器 

public class Test3 {public static void main(String[] args) {// 目标:理解this(...)调用兄弟构造器// 创建对象,存储一个学生的数据。Student s1 = new Student(name: "张无忌", sex: '男', age: 23);System.out.println(s1);Student s2 = new Student(name: "赵敏", sex: '女', age: 19);System.out.println(s2);}
}public class Student {private String name;private char sex;private int age;private String schoolName;public Student() {}public Student(String name, char sex, int age) {// this.name = name;// this.sex = sex;// this.age = age;// this.schoolName = "黑马程序员";// this调用兄弟构造器this(name, sex, age, schoolName: "黑马程序员");}public Student(String name, char sex, int age, String schoolName) {this.name = name;this.sex = sex;this.age = age;this.schoolName = schoolName;}public String getName() {return name;}
}

2.多态

        多态是在继承/实现情况下的一种现象,  表现为:  对象多态  和 行为多态

// Test.java
package com.itheima.polymorphism1;public class Test {public static void main(String[] args) {// 目标:认识多态的代码。// 1. 对象多态,行为多态。Animal a1 = new Wolf();a1.run(); // 方法:编译看左边,运行看右边System.out.println(a1.name); // 成员变量:编译看左边,运行看左边Animal a2 = new Tortoise();a2.run(); // 方法:编译看左边,运行看右边System.out.println(a2.name); // 成员变量:编译看左边,运行也看左边}
}// Animal.java
package com.itheima.polymorphism1;public class Animal {String name = "动物";public void run() {System.out.println("动物会跑~~~");}
}// Wolf.java
package com.itheima.polymorphism1;public class Wolf extends Animal {String name = "狼";@Overridepublic void run() {System.out.println("奔跑的狼~~~");}
}// Tortoise.java
public class Tortoise extends Animal {String name = "乌龟";@Overridepublic void run() {System.out.println("乌龟跑的贼慢~~~");}
}

2.1  多态的好处

        在多态形态下,  右边对象是解耦合的,  更便于扩展和维护

// Test.java
public class Test {public static void main(String[] args) {Animal a1 = new Tortoise();a1.run();Wolf w = new Wolf();go(w);Tortoise t = new Tortoise();go(t);}// 宠物游戏:所有动物都可以送给这个方法开始跑步。// 多态的好处2:父类类型的变量作为参数,可以接收一个子类对象public static void go(Animal a) {System.out.println("开始。。。");a.run();}
}// Wolf.java
package com.itheima.polymorphism2;public class Wolf extends Animal {String name = "狼";@Overridepublic void run() {System.out.println("奔跑的狼~~~");}
}// Tortoise.java
// 假设Tortoise类和Wolf类在同一个包中,或者已经正确导入
public class Tortoise extends Animal {String name = "乌龟";@Overridepublic void run() {System.out.println("乌龟跑的贼慢~~~");}
}// Animal.java
// 假设Animal类和Wolf类在同一个包中,或者已经正确导入
public class Animal {String name = "动物";public void run() {System.out.println("动物会跑~~~");}
}

多态下会产生的一个问题, 怎么解决?

        多态性下不能使用子类的独有功能 ( 可以在多态下的类型转换解决 )

2.2  多态下的类型转换

public static void go(Animal a){System.out.println("开始。。。");a.run();// a.shrinkHead(); // 报错,多态下不能调用子类独有功能。// Java建议强制转换前,应该判断对象的真实类型,再进行强制类型转换。if(a instanceof Wolf){Wolf w1 = (Wolf) a;w1.eatSheep();}else if(a instanceof Tortoise){Tortoise t1 = (Tortoise) a;t1.run();}
}
http://www.lryc.cn/news/583416.html

相关文章:

  • uniapp小程序无感刷新token
  • Docker 高级管理--容器通信技术与数据持久化
  • [论文阅读] 软件工程 | 一篇关于开源许可证管理的深度综述
  • 图像处理中的模板匹配:原理与实现
  • LabVIEW前面板颜色修改
  • 利用编码ai工具cursor写单元测试
  • MCP快速入门—快速构建自己的服务器
  • 如何使用Pytest进行测试?
  • Android-重学kotlin(协程基础)新学习总结
  • MATLAB基于voronoi生成三维圆柱形
  • 2025年人工智能、虚拟现实与交互设计国际学术会议
  • Matlab-Simulink之步长
  • PlantUML 在 IDEA 中文版中的安装与使用指南
  • VR重现红军过雪山:一场穿越时空的精神洗礼​
  • VR/AR在HMI中的创新应用:远程协作与维修的沉浸式体验
  • 【图像处理基石】图像超分辨率有哪些研究进展值得关注?
  • 【SQL】使用UPDATE修改表字段的时候,遇到1054 或者1064的问题怎么办?
  • git上传大文件启用LFS git报错 the remote end hung up unexpectedly
  • ReactNative【实战系列教程】我的小红书 6 -- 购物(含商品搜索、商品分类、商品列表)
  • 【RidgeUI AI+系列】猜密码游戏
  • 2025快手创作者中心发布视频python实现
  • Python 项目快速部署到 Linux 服务器基础教程
  • Android 系统默认代码,如何屏蔽相册分享功能
  • cJSON数组操作函数使用指南
  • AJAX 学习
  • Go语言高级面试必考:切片(slice)你真的掌握了吗?
  • 11.7 ChatGPT奖励模型完全解读:RLHF核心技术深度剖析与Hugging Face实战
  • 从传统到智能:地质灾害风险评估、易发性分析与灾后重建;AI大语言模型DeepSeek、ChatGPT、GIS、Python和机器学习深度融合
  • 李宏毅NLP-9-语音转换
  • 大数据在UI前端的应用深化:用户行为模式的挖掘与预测性分析