0、向上转型复习
(1)类和类之间的关系
①一种是继承关系,必须满足is a原则(Dog is an Animal)
②另一种组合关系,组合关系has a原则,表示一种包含关系被包含的类中的属性与方法也在包含的类中(School has a Student)
(2)protected修饰符
①在不同包的具有继承关系的类之间,在子类之中可以访问父类中protected权限的属性与方法,在子类之外,通过子类对象仍然无法访问protected域
②在同一个包中的不同类(不一定有继承关系),可以访问彼此protected修饰的属性与方法
③四大权限修饰符都针对的是在哪些类\包中的可见性问题,与具体对象无关!!
(3)多态∶
①定义:相同的方法/行为,经由不同的对象,表现出了不同的行为,这种特性称为多态性也称为动态绑定(编译阶段无法确定参数具体类型,运行时调用才知道具体是什么)
②实现多态有三个必不可少的要求
· 必须在继承体系下使用多态
· 使用的方法必须经过子类重写
· 最终通过父类的引用来调用重写方法(向上转型)
(4)方法重写与方法重载
①方法重载:在同一个类中,定义了若干个方法名称相同,参数列表类型或个数不同的一组方法,称为重载方法。方法重载与返回值无关 -> 静态绑定(在编译阶段通过方法参数就能确定到底调用的是哪个方法)
②方法重写:在有继承关系的类之间,子类定义了和父类除了权限不同之外,方法名称,参数列表,返回值(向上转型的返回值例外)都相同的方法称为子类重写了父类的方法
· 子类方法权限>=父类方法权限,private权限不包含在内
· 关于重写方法的返回值,除了向上转型以外,返回值类型必须都相同,毫无相关的类返回值,基本类型不同的返回值都不算重写方法!
(5)向上转型︰
①语法:父类名称 父类引用 = new子类实例(); //天然发生的向上转型
②调用【父类引用.方法();】时
· 这个方法到底调用的是子类中的方法还是父类中的方法,只要new的对象所在的子类重写了该方法,则一定调用子类重写后的方法(以子类为准,优先在子类中寻找该方法)只有子类没有重写该方法,才会调用父类中的方法
③向上转型最大优势在于参数统一化,通过父类引用可以接收所有的子类对象
1、final关键字∶称为Java中的终结器
(1)final修饰属性
①final修饰的属性称为常量,被final修饰的变量,一旦初始化之后,值不能修改。
②被final修饰的引用类型,仍然是值不能改,保存的地址不能改。也就是说,引用只能指向当前对象,不能更改指向,至于对象内部如何修改都是可以的。
(2)final修饰方法
①final修饰方法,表示该方法不能被覆写!
· 无论当前类有多少子类,通过任何对象调用test方法,都只有这一种行为。若父类中的有些方法/行为,不允许子类随意修改,将该方法使用final修饰
(3)final修饰类
①final修饰类,表示该类无法被继承,该类没有任何子类!
· 若当前类中的所有属性与方法都不允许随意修改/覆盖,则使用final修饰,只要没有任何子类就能保证所有人用到的这个类的对象,大家都是一样的表现
· JDK中String就使用了final进行修饰
2、向上转型
(1)父类名称 父类引用 = new 子类实例();
①到底能通过父类引用"∵"(调用哪些方法),要看父类,这些方法必须在父类中定义过
②至于调用的这个方法到底表现出怎样的行为,要看new的哪个子类,若子类重写了该方法,则调用子类重写后的方法
· 若需要调用Dog类中独有的bite方法,就需要脱掉Animal外衣,还原为Dog类的引用才可以。这种操作就称为向下转型
3、向下转型
(1)语法:
子类名称 子类实例 = (子类名称) 父类引用
(2)若Animal类有吃饭睡觉方法,狗有咬方法,此时Animal animal = new Dog(); animal.bite(); //此时无法访问必须通过向下转型
Dog dog = (Dog) animal; //注意后面是animal不是Animal!!! dog.bite(); //此时才可实现bite方法(3)向下转型由于存在类型的强转,有可能会出现类型转换异常。
①向下转型必须发生在有继承关系的类之间,毫无关系的类,对象不能发生向下转型(强转)
②发生向下转型之前,必须先发生向上转型!!!建立父类引用和具体子类实例的关系~~
(4)由于向下转型存在类型转换异常的风险,引入了instanceof关键字
①用法: 引用名称 instanceof 类名称
②返回布尔值
· true:表示当前引用确实指向对应类的实例,可以强转
· false:表示当前引用与对应类的实例毫无关系,不能强转
③一般使用该关键字搭配分支语句来进行向下转型if(animal instanceof Dog){ Dog dog = (Dog) animal; }(5)什么时候会用到向下转型
①通过相同的父类引用接收了子类实例之后fun(Animal animal) { //需要在fun方法中,调用某个具体子类独有的方法/属性,需要用到向下转型 }
4、向下转型的具体应用
(1)Object类的equals方法
· Object类是Java中所有类的父类,所有类默认继承自Object类
· toString():将当前对象转变为字符串对象,默认的方法就是【输出包名称.类名称@处理后的地址】
· 若我们需要在当前类中打印输出某些属性值,覆写toString方法即可
(2)关于对象比较相等
· "=="操作符只能比较两个引用的值是否相同:两个引用指向的对象是否是同一个对象
· 若需要判断两个不同对象属性值是否相同,需要使用equals方法来判断,必须要学会equals方法的覆写
(3)equals代码
①默认的equals方法代码
public boolean equals (Object obj) { //Object类是所有类的父类,因此都可以向上转型通过Object类型来接收 return (this == obj); }· 和使用 "==" 效果一致,判断传入的对象到底是不是同一个对象
②覆写equals方法public boolean equals(Object obj){ //判断当前对象是否和传入引用指向同一个对象 if(this == obj){ return true; } //判断obj这个引用是否指向的就是Student类型的对象 if(!(obj instanceof Student)){ return false; }else{ //说明此时obj确实是Student类型的对象,且和当前对象不是同一个对象 //需要比较当前对象的属性和传入对象的属性是否相等 //此时需要还原obj引用为当前Student类型的引用 Student stu = (Student) obj; return this.name == stu.name && this.age == stu.age; } }
5、面向对象开发的三大特性
封装(保护性/易用性)、继承(代码复用)、多态(参数统一化)
(1)多态的优势︰参数统一化,降低圈复杂度(避免使用大量的if-else分支)
(2)实现Sharp父类,Triangle、Cycle、Rectangle子类的draw()方法
①不使用多态时://假设用户现在需要打印多个形状,没有多态 Cycle cycle = new Cycle(); Triangle triangle = new Triangle(); Rectangle rectangle = new Rectangle(); string[] sharps = {"cycle","triangle","cycle","rectangle"}; //用户需要打印这四个图形 for (String s : sharps){ //遍历用户指令,按照指令打印对应的图形 if (s.equals( "cycle")){ cycle.draw( ); }else if (s.equals("triangle")) { triangle.draw(); }else if (s.equals( "rectangle")){ rectangle.draw(); } }· 有多少种图形类,就得有多少个分支(if和else if)当现在拓展了新的图形类,就得修改用户的使用代码,增加分支
②使用多态来降低圈复杂度//无论是什么图形,最终都保存在Sharp对象数组中 Sharp[] sharps = { new cycle(), new Rectangle(), new Triangle(), new Flower() }; //打印该图形,无论啥图形,最终都要调用sharp中的draw方法进行打印 for (Sharp sharp : sharps) { sharp.draw(); }· 再拓展新的子类时,对于打印输出,一行代码都不变
要想使用多态,必须得有继承。子类还必须得覆写相关的方法。没有方法重写,就没有多态,若子类中不覆写这个方法,父类无法强制要求子类覆写方法,于是产生了抽象类
6、抽象类
(1)定义︰所谓的抽象类就是比普通类多了一些抽象方法而已,是普通类的超集(普通类有的,抽象类都有)!
抽象类和抽象方法使用abstract关键字来定义,抽象方法所在的类一定是抽象类
(2)抽象类和抽象方法的定义public abstract class Animal{ public abstract void eat(); }· 抽象方法所在的类一定是抽象类,抽象类使用abstract来声明,可以不包含任何抽象方法抽象方法使用abstract来声明,只有方法声明,不包含方法体!!! !!
· 抽象类必须有子类!!抽象方法必须被子类覆写(子类是普通类)就可以对子类中的行为做出要求,这样的话就可以更好的保证多态的正确运行
· abstract和final这俩关键字不能同时出现
· abstract和private这俩关键字不能同时出现,private修饰的方法不能重写,abstract修饰的方法必须被重写
(3)子类继承抽象类,必须覆写抽象类中的所有抽象方法(前提∶子类是普通类);若子类也是抽象类,可以选择性的覆写抽象方法(也可以不写)
文章详细阐述了Java中的向上转型、final关键字的使用以及多态的概念和实现。向上转型允许通过父类引用调用子类的方法,实现参数统一化;final关键字用于修饰属性、方法和类,确保其不可变或不可被继承;多态则强调在继承体系下,通过父类引用调用子类重写的方法,实现不同的行为。此外,文章还提到了方法重写、重载的原则以及抽象类的作用,强调了抽象方法必须在子类中被覆写。
2076

被折叠的 条评论
为什么被折叠?



