我宁愿写bug⚠️,也不愿什么都不做 ❗️
💚哈喽!大家好!💚
❤️我是 一看就会,一写就废 的 浩浩🔍❤️
💙让我带你编程带你飞,带你飞进垃圾堆!💙
💜 如果对你有所帮助,请给我点个赞👍!💜
键盘敲烂💥,工资过万💰
📌
封装
1. 封装的作用和意义
- 面向对象的三个基本特征:封装、继承、多态
- 封装的定义:
- 把对象的属性和操作结合为一个独立的整体,尽可能隐藏对象的内部实现细节。
- 程序设计追求“高聚合,低耦合”。(把复杂性封装起来,用的时候尽可能的简单)
- 高聚合:就是类的内部数据操作细节自己完成,不允许干涉。
- 低聚合:是仅暴露少量的方法外部使用,尽量方便外部调用。
2. 封装的优点
- 提高代码的安全性
- 提高代码的复用性
- “高内聚”:封装细节,便于修改内部代码,提高可维护性
- “低耦合”:简化外部调用,便于调用者使用,便于扩展和写作。
3. 封装的细节
- 属性的私有化
- 提供公开的 get、set 方法
- 一般使用 private 访问权限修饰来修饰成员变量
- 提供相应的 get、set 方法来访问相关属性,这些方法通常是 public 修饰的。以提供对属性的赋值与读取操作
- 一些只用于本类的辅助性方法,可以使用 private 修饰
- 希望其他类调用的方法用 public 修饰。
继承
1. 继承的概念及意义
- 继承概念:
- 所谓继承是指一个类的定义可以基于另外一个已经存在的类,即子类基于父类,从而实现父类代码的重用,子类能吸收已有类的数据属性和行为,并能扩展新的能力。
- 继承的意义:
- 通过使用继承我们能够非常方便地复用以前的代码,能够大大的提高开发的效率。
2. 继承的声明形式
-
声明形式
[访问权限修饰符][修饰符] 子类名 extends 父类名 { 子类体 }
-
子类能够使用父类的非私有的成员变量和成员方法,并能扩展新的功能。
3. 继承的优点
- 提高了代码的复用性
- 多个类相同的成员可以放到同一个类中(父类)
- 提高了代码的维护性
- 如果功能的代码需要修改,修改一处即可
- 让类与类之间产生了关系,是多态的前提
- 其实这也是继承的一个弊端:类的耦合性很强
4. 继承的特点以及注意事项
-
Java 只支持单继承,不支持多继承。
- 一个类只能有一个父类,不可以有多个父类
-
Java 支持多层继承(继承体系)
class A {} class B extends A {} class C extends B {}
-
继承的注意事项
- 子类只能继承父类所有非私有的成员(成员方法和成员变量)
- 子类不能继承父类的构造方法,但是可以通过super(后面讲)关键字去访问父类构造方法。
5. 继承中成员变量的关系
- 在子类方法中访问一个变量
- 首先在子类局部范围找
- 然后在子类成员范围找
- 最后在父类成员范围找(肯定不能访问到父类局部范围)
- 如果还是没有就报错。(不考虑父亲的父亲…)
6. super 关键字
-
super 的用法和 this 很像
- this 代表本类对应的引用。
- super 代表父类存储空间的标识(可以理解为父类引用)
-
用法 ( this 和 super 均可如下使用)
- super(…)或者this(…)必须出现在第一条语句上
7. 继承中构造方法的关系
- 子类中所有的构造方法默认都会访问父类中无参数的构造方法
- 为什么呢?
- 因为子类会继承父类中的数据,可能还会使用父类的数据。子类初始化之前,一定要先完成父类数据的初始化。
- 每一个构造方法的第一条语句默认都是:super()
- 如果父类中没有构造方法,该怎么办呢?
- 子类通过 super 去显示调用父类其他的带参的构造方法
- 子类通过 this 去调用本类的其他构造方法:本类其他构造也必须首先访问了父类构造
8. 继承中成员方法的关系
- 在子类方法中访问一个方法
- 首先在子类局部范围找
- 然后在子类成员范围找
- 如果还是没有就报错。(不考虑父亲的父亲…)
9. 方法覆盖(重写)
- 定义:
- 子类可以重写父类中某一个方法,称为方法覆盖,也称方法重写,是继承中非常重要的知识点。如果子类需要修改从父类继承到的方法的方法体,就可以使用方法覆盖
- 方法覆盖的原则
- 同名
- 同参
- 通返回值
- 访问权限不能缩小
多态
0. 引子
-
案例一:张女士喂小动物
1. 创建类Women feed(Dog dog) {} feed(Cat cat ){} 方法 1. 创建Dog类 eat(){}方法 1. 创建Cat类 eat(){}方法 1. 创建测试类 1. 创建Women对象 2. 创建Dog对象 3. 创建Cat对象 4. 调用Women对象.feed(Dog对象) 5. 调用Women对象.feed(Cat对象) 1. 增加Monkey对象 1. 创建Monkey类 eat(){}方法 2. 类Women 增加 feed(Monkey monkey) {} 方法
-
有什么不足?
- 每增加一个动物,就要增加一个 feed() {} 方法
-
案例二:张女士喂小动物
- 增加小动物的父类Animal: eat()
- 让所有小动物都继承Animal
- 类Women只保留一个方法 feed(Animal animal) 实现喂食所有动物
1. 多态概念
- 面向对象的三个基本特征:封装、继承、多态
- 多态的含义是:对外的一种表现形式,内在具有多种具体实现。
- java 中多态的具体体现
- 方法重载
- 方法覆盖
- 多态参数
2. 方法的重载
-
方法重载的概念
-
在 Java 类中如果有多个同名但是参数不同的方法就称为 “ 方法的重载 ”。
编译器会根据调用时传递的实际参数自动判断具体调用的是哪个重载方法。
-
-
方法重载的三大原则
- 方法名相同
- 参数不同(数量不同、类型不同、顺序不同)
- 同一作用域
- 注意:方法重载跟方法的返回值类型没有任何关系,只有返回值不同的方法不能构成重载。请勿将功能完全不一样的方法进行重载!
-
方法重载的好处
- 方便阅读及程序的维护,优化了程序设计。
3. 向上造型
- 向上造型—自动类型提升
- 定义:子类类型自动转换为父类类型,不需要强转.父类型的引用指向子类对象,对象向上造型也叫自动类型提升
- 作用:提高程序可拓展性
- 对象dog 可以调用狗类中所有的方法(包括宠物类中所有非私有方法)
- p 只能调用宠物类中定义的方法,狗类扩展的新方法不能调用
4. 多态环境下对属性和方法的调用
1. 多态环境下对非静态方法的调用
父类型 变量名=new 子类型();
- pet对象: 编译看左边 ,运行看右边
public class Pet {
public void m1(){
System.out.println("这是Pet的m1()方法");
}
public void toHostpital(){
System.out.println("宠物看病");
}
}
public class Dog extends Pet {
public void toHostpital(){
System.out.println("狗看病");
}
public void shout(){
System.out.println("Dog.shout()方法");
}
}
public class MasterTest {
public static void main(String[] args) {
Pet p=new Dog();//父类型的引用指向子类对象
p.m1();//子类没重写调用的是父类的方法
p.toHostpital();//子类重写方法调用的是子类对象重写的方法
}
}
2. 多态性的情况下对静态成员方法的调用
- 对静态成员方法的调用:编译运行都看左边
public class Pet {
public void m1(){
System.out.println("这是Pet的m1()方法");
}
public void toHostpital(){
System.out.println("宠物看病");
}
public static void m2(){
System.out.println("Pet.m2()static方法");
}
}
public class Dog extends Pet {
public void toHostpital(){
System.out.println("狗看病");
}
public void shout(){
System.out.println("Dog.shout()方法");
}
public static void m2(){
System.out.println("Dog.m2()static方法");
}
}
public class MasterTest {
public static void main(String[] args) {
Pet pet =new Dog();
pet.m2();//静态的成员方法编译运行都看左边,调用的是父类的m2()方法
}
}
3. 成员变量
- 对成员变量的调用:编译运行都看左边。
- 注意:变量不存在被子类覆写这一说法,只有方法存在覆写。
所以,静态变量也是编译和运行都看等号左边。
class Pet{
int num = 3;
}
class Dog extends Pet{
int num = 4;
}
Pet pet = new Dog()
System.out.println( pet.num ) ; //调用的是宠物类中的成员变量,输出是3,说明调用的是父类的成员变量的值
4. 结论
- 编译期和运行期相同的情况:A a = new A();
- 编译期和运行期不同的情况
- 父类和子类有相同的成员变量(静态和非静态),多态下访问的是父类的成员变量。
- 当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法。
- 当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法
5. 多态参数
-
定义:方法的形式参数类型是父类类型,而传递的实际参数可以是该父类任意子类的对象
-
方法参数多态性的好处:提高代码的扩展性
总结
1.多态:一种行为,有多种不同形式的表现
2.多态的具体体现
1.方法重载
2.方法覆盖
3.多态参数
3.方法重载:同一个类中有多个同名的方法,但是参数不同(参数的类型不同,参数的顺序不同,参数的个数不同),叫做方法的重载
4.对象向上造型:子类类型自动转换为父类类型,不需要强转
5.多态环境下对属性和方法的调用
1)多态环境下对非静态方法的调用
父类型 变量名=new 子类型();
pet对象: 编译看左边 ,运行看右边
2)多态性的情况下对静态成员方法的调用
对静态成员方法的调用:编译运行都看左边
3)多态性的情况下对非静态成员变量,静态成员变量的调用
对非静态,静态成员方法的调用:编译运行都看左边
换言之:
编译期和运行期不同的情况;
• 父类和子类有相同的成员变量(静态和非静态),多态下访问的是父类的成员变量。
• 当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的
是子类的成员方法。
• 当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问
的是父类的静态方法
6.多态参数:方法的形式参数类型是父类类型,而传递的实际参数可以是该父类任意子类的对象
7.多态作为返回值类型:返回值是父类型的引用,方法体的return返回的是子类对象
6. 多态的前提与弊端
- 多态的前提:类之间有关系:继承或者实现
- 多态的弊端:只能调用父类的方法,不能调用子类特有的方法
7. 对象向下造型
-
定义:父类型引用转换为子类型
-
公式:子类型 变量名=(子类型)父类型变量名
-
作用:为了使用子类中特有的方法
Dog d=(Dog)p;//向下造型 d.shout();//能调用子类扩展的方法
8. 多态的注意事项
-
不能把父类向下转换为子类类型 Pet pet=new Pet(); Dog dog=(Dog)pet;
-
不具备继承关系的类不能互转
Pet p=new Cat();//父类型的引用指向子类对象 Dog d=(Dog)p;//不具有继承关系的类不能互转 Exception in thread "main" java.lang.ClassCastException:Cat cannot be cast to Dog
-
对于转型,只能强制转换成这个对象的运行期类型
Pet p=new Dog();//父类型的引用指向子类对象 Dog d=(Dog)p;//向下造型:只能强制转换成这个对象的运行期类型
总结
1. 多态转型:
- 向上造型(自动)
- 向下造型(强制)
2. 多态向上转型的特点:
- 限制了对子类特有方法的访问,提高代码的扩展性
3. 多态向下转型的特点:
- 为了使用子类特有方法
9. instanceof 运算符
- 作用:运算符 instanceof 用来判断对象是否属于某个类的实例
- 公式:对象名 instanceof 类名
该表达式为一个boolean表达式,如果对象的类型是后面提供的类或其子类,则返回true,反之返回false - 案例:
1.Animal eat()
1.Dog:eat() lookingHome()
2.Cat:eat() catchMouse()
2.AnimalTest
判断Dog类型或者Cat类型
public class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
package t01;
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗啃骨头");
}
public void lookingHome(){
System.out.println("狗看家");
}
}
package t01;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
package t01;
public class AnimalTest {
public static void main(String[] args) {
//创建对象
Animal animal=new Cat();
animal.eat();//猫吃鱼
//判断是否是狗对象类型
if (animal instanceof Dog){
//强转
Dog dog= (Dog) animal;
//调用特有的方法
dog.lookingHome();//狗看家
}
if (animal instanceof Cat){
//强转
Cat cat= (Cat) animal;
//调用方法
cat.catchMouse();//猫抓老鼠
}
}
}