2022.3.29 多态、instanceof、强制转换
快捷键:重写方法与构造函数ALT+INS
-
动态编译:类型:可扩展性
-
即同一方法可以根据发送对象的不同(s1,s2)而采用多种不同的行为方式。
-
一个对象的实际类型是确定的。但可以指向对象的引用的类型有很多(父类,有关系的类)
-
多态存在的条件
-
有继承关系
-
子类重写父类方法
-
父类引用指向子类对象
-
-
多态的定义与使用格式
-
定义格式:父类类型 变量名=new 子类类型();
-
-
理解含义
-
多态是同一个行为具有多个不同表现形式或形态的能力。
-
多态就是同一个接口,使用不同的实例而执行不同操作。
-
-
注意:多态是方法的多态,属性没有多态性。
1 package com.oop.demo08; 2 3 public class Person { 4 public void run(){ 5 System.out.println("run"); 6 } 7 }
1 2 package com.oop.demo08; 3 4 public class Student extends Person{ 5 @Override 6 public void run() { 7 System.out.println("son"); 8 } 9 public void eat(){ 10 System.out.println("eat"); 11 } 12 }
1 package com.oop; 2 3 import com.oop.demo08.Person; 4 import com.oop.demo08.Student; 5 6 //一个项目应该只存在一个main()方法 7 public class Application { 8 public static void main(String[] args) { 9 //一个对象的实际类型是确定的 10 //new Student(); 11 //new Person(); 12 13 //可以指向的引用类型就不确定了 14 15 Student s1 = new Student(); 16 //可以指向子类,但不能调用子类独有的方法 17 //编译看左边,运行看右边 18 Person s2 = new Student();//父类的引用指向子类 19 20 21 //对象(s1、s2)能执行哪些方法,主要看左边的类(Person、Student)中的方法有没有(继承的也算有),如果有就执行右边实例中的方法(new Student) 22 s2.run();//son,子类重写了父类的方法,执行子类的方法,子类没有重写父类的方法,执行父类的方法 23 s1.run();//son 24 25 } 26 27 }
1 package com.oop; 2 3 import com.oop.demo08.Person; 4 import com.oop.demo08.Student; 5 6 //一个项目应该只存在一个main()方法 7 public class Application { 8 public static void main(String[] args) { 9 //一个对象的实际类型是确定的 10 //new Student(); 11 //new Person(); 12 13 //可以指向的引用类型就不确定了 14 15 Student s1 = new Student(); 16 //可以指向子类,但不能调用子类独有的方法 17 //编译看左边,运行看右边 18 Person s2 = new Student();//父类的引用指向子类 19 20 21 //对象(s1、s2)能执行哪些方法,主要看左边的类(Person、Student)中的方法有没有(继承的也算有),如果有就执行右边实例中的方法(new Student) 22 s2.run();//son,子类重写了父类的方法,执行子类的方法,子类没有重写父类的方法,执行父类的方法 23 s1.run();//son 24 25 } 26 27 }
多态注意事项
-
多态是方法的多态,属性没有多态
-
父类和子类,有联系,不能是类型不一致(不能是这样的:String s1 = new Student(),应是引用类型变量指向new),
-
存在条件:继承关系,方法需要重写,父类引用指向子类对象!father f1 = new Student();
以下修饰的都不能被重写
-
static 方法,属于类,他不属于实例
-
final常量
-
private方法
-
作用:用来判断某个对象是否属于某种数据类型。
-
instanceof是Java的一个二元操作符(运算符),也是Java的保留关键字。它的作用是判断其左边对象是否为其右边类的实例,返回的是boolean类型的数据。 可以用来判断继承中的子类的实例是否为父类的实现
-
类的实例包含本身的实例,以及所有直接或间接子类的实例
-
instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误
例:
1 //System.out.println(X instanceof Y);能不能编译通过,取决于有没有父子关系(Object类与Student类有父子关系) 2 //true:X指向的实际类型是不是Y的子类型
1 package com.oop.demo08; 2 3 public class Person { 4 public void run(){ 5 System.out.println("run"); 6 } 7 }
1 package com.oop.demo08; 2 3 public class Student extends Person { 4 public void go(){ 5 System.out.println("go"); 6 } 7 8 9 }
1 package com.oop.demo08; 2 3 public class Teacher extends Person{ 4 5 }
1 package com.oop; 2 3 import com.oop.demo08.Person; 4 import com.oop.demo08.Student; 5 import com.oop.demo08.Teacher; 6 7 //一个项目应该只存在一个main()方法 8 public class Application { 9 public static void main(String[] args) { 10 //Object>String 11 //Object>Person>Student 12 //Object>Person>Teacher 13 14 //System.out.println(X instanceof Y);能不能编译通过,取决于有没有父子关系Object Student 15 //true:X指向的实际类型是不是Y的子类型 16 Object object = new Student(); 17 System.out.println(object instanceof Student);//true 18 System.out.println(object instanceof Person);//true 19 System.out.println(object instanceof Object);//true 20 //当前对象object(引用变量)指向Student()类型,与Teacher()不是父子关系 21 System.out.println(object instanceof Teacher);//false 22 System.out.println(object instanceof String);//false 23 24 Person person= new Student(); 25 System.out.println(person instanceof Student);//true 26 System.out.println(person instanceof Person);//true 27 System.out.println(person instanceof Object);//true 28 System.out.println(person instanceof Teacher);//false 29 //System.out.println(person instanceof String);编译报错 30 31 Student student= new Student(); 32 System.out.println(student instanceof Student);//true 33 System.out.println(student instanceof Person);//true 34 System.out.println(student instanceof Object);//true 35 //System.out.println(student instanceof Teacher);编译报错 36 //System.out.println(person instanceof String);编译报错 37 38 } 39 40 }
强制转换
1 package com.oop.demo08; 2 3 public class Person { 4 public void run(){ 5 System.out.println("run"); 6 } 7 }
1 package com.oop.demo08; 2 3 public class Student extends Person { 4 public void go(){ 5 System.out.println("go"); 6 } 7 }
1 package com.oop; 2 3 import com.oop.demo08.Person; 4 import com.oop.demo08.Student; 5 import com.oop.demo08.Teacher; 6 7 //一个项目应该只存在一个main()方法 8 public class Application { 9 public static void main(String[] args) { 10 //类型之间转化:自动转化 低到高(子 父) 向上转型 11 12 char c = 'a'; 13 //高 低 14 int c1 = c; 15 16 //高 低 相当于赋值,把Student()赋值给person 17 Person person = new Student(); 18 //person.go();不能直接调用 19 20 //与上面一样:子类转化为父类可能会丢失一些自己的方法 21 Student student = new Student(); 22 Person p = student; 23 //p.go();不能运行 24 25 26 //将person这个对象强制转化为Student就可以使用Student类的方法 27 Student s = (Student) person;//s用于接收 28 s.go(); 29 30 ((Student)person).go(); 31 32 } 33 34 35 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~