1.什么是多态顾名思义多态就是事物的多种形态。简单来说就是“同一个接口不同的实现。”多态的表现形式父类类型 对象名new 子类类型多态的前提有继承/实现关系有父类引用指向子类对象2.多态的使用场景在学生管理系统中我们会有学生类型老师类型管理员类型在每个成员使用之前都必须注册账号。//注册方法 public boolean register(Student s){ }在这里如果我们注册方法的形参是Student类型的话那么同样也需要形参是Teacher、Administrator的方法增加了代码的复用性只有形参不同而需要的注册功能是相同的还得再写一个方法。那么我们可以利用多态来解决这种问题。例如创建一个父类Personpublic class Person { private String name;//姓名 private String username;//账号名 private String password;//密码 public Person() { } public Person(String name, String username, String password) { this.name name; this.username username; this.password password; } public String getName() { return name; } public void setName(String name) { this.name name; } public String getUsername() { return username; } public void setUsername(String username) { this.username username; } public String getPassword() { return password; } public void setPassword(String password) { this.password password; } }在创建子类Student、Teacherpublic class Student extends Person { public Student(){ super(); } public Student (String name, String username, String password){ super( name, username, password); } } public class Teacher extends Person { public Teacher(){ super(); } public Teacher(String name, String username, String password){ super( name, username, password); } }测试类Testpublic class Test { public static void main(String[] args) { Student s new Student(张三,zhang,123456); Teacher t new Teacher(李四,li,456789); //注意下面的register方法的形参是Person类型的而我们这里穿过去的实参分别是Student、Teacher类型的 register(s); register(t); } //注册方法 public static void register(Person p){ System.out.println(姓名是p.getName()注册成功账号是p.getUsername()密码是p.getPassword()); } }输出结果通过上面的例子我们不难看出来利用父类Person作为register作为形参可以接受子类的所有对象这样我们解决了一开始的问题。方法的形参是父类就可以接受子类所有的对象。3.多态调用成员的特点变量调用编译看左边运行也看左边。在java文件编译成class文件时先看父类中有没有这个变量如果有那就可以编译成功反之则不能。运行看左边在代码最后的运行结果用的是父类当中的该变量并非子类。方法调用编译看左边运行看右边。编译看左边先看父类中有没有这个方法如果有就编译成功没有则失败。运行看左边在代码真正用的是子类当中的方法。如果子类没有重写父类当中的方法那就是用父类。变量调用例子先了解变量编译看左边创建父类Person、子类Studentpublic class Person { String name; } public class Student extends Person { String work学习; }测试Testpublic class Test { public static void main(String[] args) { Person pnew Student (); /*编译看左边因为name是父类Person中的变量所以下面p.name能够编译成功 而s.name就不会编译成功会显示红色报错。 */ String Name p.name; String Name1 s.name;//编译器在这里会高亮报错 //同样Student 中特有的子类work也无法编译成功 String works.work; } }变量运行也看左边创建父类Person、子类Studentpublic class Person { String name张三; } public class Student extends Person { String name李四; }测试Testpublic class Test { public static void main(String[] args) { Person pnew Student (); System.out.println(p.name); } }输出结果最后运行结果是父类中的name。多态方法调用的例子类似可以自己尝试。4.多态的优缺点先说优点优点方法中使用父类作为参数类型可接受所有子类类型和父类类型同一接口不同实现。如果方法重写利用多态调用方法可以不同子类中重写的方法。通过目录2中代码我们已经可以看出优点1接下来举个例子来体现优点2。例如创建一个父类Personpublic class Person { public void work(){ System.out.println(每个人都需要工作); } }子类Student、Teacherpublic class Student extends Person { Override public void work(){ System.out.println(学生的工作是学习); } } public class Teacher extends Person { Override public void work(){ System.out.println(老师的工作是教书); } }测试Testpublic class Test { public static void main(String[] args) { Student s new Student(); Teacher t new Teacher(); s.work(); t.work(); } }输出结果所以这个例子我们可以知道优点2。再了解过优点后我们来看一下缺点。缺点多态下不能使用子类特有的功能。此缺点下面会有破解方案例子创建父类对象Personpublic class Person { public void work(){ System.out.println(工作); } }子类Student、Teacherpublic class Student extends Person { public void study(){ System.out.println(我要好好学习); } } public class Teacher extends Person { public void teach(){ System.out.println(教书育人); } }测试Testpublic class Test { public static void main(String[] args) { Person p1new Student (); Person p2new Teacher(); /*study、teach分别是子类p1、p2中特有的功能由于他们的父类Person中没有 所以下面两行代码是会报错的*/ p1.sutdy; p2.teach; } }5.多态当中的类型转换自动类型转换从子到父又称为向上转型子类对象自动转换为父类类型小变大。强制类型转换从父到子又称为向下转型子类 对象变量子类父类类型的变量格式例子Person p new Student();Student s (Student)p;在目录4中了解到多态使用的缺点我们可以通过强制类型转换来解决这个问题父类、子类与目录4当中缺点的一致只有Test类不同。测试Testpublic class Test { public static void main(String[] args) { Person p1new Student (); Person p2new Teacher(); Student s(Student)p1; Teacher t(Teacher) p2; s.study(); t.teach(); } }输出结果不难看出再通过强制类型转换后我们可以使用子类当中特有的功能。注意间接父类 爷爷直接父类 爸爸子类 儿子我们在创建爸爸的对象赋值给了爷爷类型。代码Ye ye new Ba();再进行强制转换时只能将爷爷强转到爸爸类型不能转成儿子类型。6.instanceof关键字所以接下来我们引入instanceof关键字用于判断多态中是否能进行强转。public class Test { public static void main(String[] args) { // 创建爸爸对象赋值给爷爷类型 Ye ye new Ba(); // 使用instanceof判断能否转换 if (ye instanceof Ba) { System.out.println(可以转成爸爸类型); Ba ba (Ba) ye; // 强制转换 ba.work(); // 调用爸爸特有方法 } if (ye instanceof Er) { System.out.println(可以转成儿子类型); Er er (Er) ye; er.play(); } else { System.out.println(不能转成儿子类型); } } } // 爷爷类 class Ye { public void speak() { System.out.println(爷爷); } } // 爸爸类 class Ba extends Ye { public void work() { System.out.println(爸爸在工作); } } // 儿子类 class Er extends Ba { public void play() { System.out.println(儿子在玩耍); } }输出结果回到开头的注册系统正是因为用了多态我们只写了一个 register(Person p) 方法就能处理所有类型的人员注册。如果不用多态Student、Teacher、Admin 各写一个方法代码会臃肿成什么样这只是一个小例子在日常开发中我们也会用很多使用多态的场景。希望可以帮助你理解多态。
10分钟带你搞懂多态~
1.什么是多态顾名思义多态就是事物的多种形态。简单来说就是“同一个接口不同的实现。”多态的表现形式父类类型 对象名new 子类类型多态的前提有继承/实现关系有父类引用指向子类对象2.多态的使用场景在学生管理系统中我们会有学生类型老师类型管理员类型在每个成员使用之前都必须注册账号。//注册方法 public boolean register(Student s){ }在这里如果我们注册方法的形参是Student类型的话那么同样也需要形参是Teacher、Administrator的方法增加了代码的复用性只有形参不同而需要的注册功能是相同的还得再写一个方法。那么我们可以利用多态来解决这种问题。例如创建一个父类Personpublic class Person { private String name;//姓名 private String username;//账号名 private String password;//密码 public Person() { } public Person(String name, String username, String password) { this.name name; this.username username; this.password password; } public String getName() { return name; } public void setName(String name) { this.name name; } public String getUsername() { return username; } public void setUsername(String username) { this.username username; } public String getPassword() { return password; } public void setPassword(String password) { this.password password; } }在创建子类Student、Teacherpublic class Student extends Person { public Student(){ super(); } public Student (String name, String username, String password){ super( name, username, password); } } public class Teacher extends Person { public Teacher(){ super(); } public Teacher(String name, String username, String password){ super( name, username, password); } }测试类Testpublic class Test { public static void main(String[] args) { Student s new Student(张三,zhang,123456); Teacher t new Teacher(李四,li,456789); //注意下面的register方法的形参是Person类型的而我们这里穿过去的实参分别是Student、Teacher类型的 register(s); register(t); } //注册方法 public static void register(Person p){ System.out.println(姓名是p.getName()注册成功账号是p.getUsername()密码是p.getPassword()); } }输出结果通过上面的例子我们不难看出来利用父类Person作为register作为形参可以接受子类的所有对象这样我们解决了一开始的问题。方法的形参是父类就可以接受子类所有的对象。3.多态调用成员的特点变量调用编译看左边运行也看左边。在java文件编译成class文件时先看父类中有没有这个变量如果有那就可以编译成功反之则不能。运行看左边在代码最后的运行结果用的是父类当中的该变量并非子类。方法调用编译看左边运行看右边。编译看左边先看父类中有没有这个方法如果有就编译成功没有则失败。运行看左边在代码真正用的是子类当中的方法。如果子类没有重写父类当中的方法那就是用父类。变量调用例子先了解变量编译看左边创建父类Person、子类Studentpublic class Person { String name; } public class Student extends Person { String work学习; }测试Testpublic class Test { public static void main(String[] args) { Person pnew Student (); /*编译看左边因为name是父类Person中的变量所以下面p.name能够编译成功 而s.name就不会编译成功会显示红色报错。 */ String Name p.name; String Name1 s.name;//编译器在这里会高亮报错 //同样Student 中特有的子类work也无法编译成功 String works.work; } }变量运行也看左边创建父类Person、子类Studentpublic class Person { String name张三; } public class Student extends Person { String name李四; }测试Testpublic class Test { public static void main(String[] args) { Person pnew Student (); System.out.println(p.name); } }输出结果最后运行结果是父类中的name。多态方法调用的例子类似可以自己尝试。4.多态的优缺点先说优点优点方法中使用父类作为参数类型可接受所有子类类型和父类类型同一接口不同实现。如果方法重写利用多态调用方法可以不同子类中重写的方法。通过目录2中代码我们已经可以看出优点1接下来举个例子来体现优点2。例如创建一个父类Personpublic class Person { public void work(){ System.out.println(每个人都需要工作); } }子类Student、Teacherpublic class Student extends Person { Override public void work(){ System.out.println(学生的工作是学习); } } public class Teacher extends Person { Override public void work(){ System.out.println(老师的工作是教书); } }测试Testpublic class Test { public static void main(String[] args) { Student s new Student(); Teacher t new Teacher(); s.work(); t.work(); } }输出结果所以这个例子我们可以知道优点2。再了解过优点后我们来看一下缺点。缺点多态下不能使用子类特有的功能。此缺点下面会有破解方案例子创建父类对象Personpublic class Person { public void work(){ System.out.println(工作); } }子类Student、Teacherpublic class Student extends Person { public void study(){ System.out.println(我要好好学习); } } public class Teacher extends Person { public void teach(){ System.out.println(教书育人); } }测试Testpublic class Test { public static void main(String[] args) { Person p1new Student (); Person p2new Teacher(); /*study、teach分别是子类p1、p2中特有的功能由于他们的父类Person中没有 所以下面两行代码是会报错的*/ p1.sutdy; p2.teach; } }5.多态当中的类型转换自动类型转换从子到父又称为向上转型子类对象自动转换为父类类型小变大。强制类型转换从父到子又称为向下转型子类 对象变量子类父类类型的变量格式例子Person p new Student();Student s (Student)p;在目录4中了解到多态使用的缺点我们可以通过强制类型转换来解决这个问题父类、子类与目录4当中缺点的一致只有Test类不同。测试Testpublic class Test { public static void main(String[] args) { Person p1new Student (); Person p2new Teacher(); Student s(Student)p1; Teacher t(Teacher) p2; s.study(); t.teach(); } }输出结果不难看出再通过强制类型转换后我们可以使用子类当中特有的功能。注意间接父类 爷爷直接父类 爸爸子类 儿子我们在创建爸爸的对象赋值给了爷爷类型。代码Ye ye new Ba();再进行强制转换时只能将爷爷强转到爸爸类型不能转成儿子类型。6.instanceof关键字所以接下来我们引入instanceof关键字用于判断多态中是否能进行强转。public class Test { public static void main(String[] args) { // 创建爸爸对象赋值给爷爷类型 Ye ye new Ba(); // 使用instanceof判断能否转换 if (ye instanceof Ba) { System.out.println(可以转成爸爸类型); Ba ba (Ba) ye; // 强制转换 ba.work(); // 调用爸爸特有方法 } if (ye instanceof Er) { System.out.println(可以转成儿子类型); Er er (Er) ye; er.play(); } else { System.out.println(不能转成儿子类型); } } } // 爷爷类 class Ye { public void speak() { System.out.println(爷爷); } } // 爸爸类 class Ba extends Ye { public void work() { System.out.println(爸爸在工作); } } // 儿子类 class Er extends Ba { public void play() { System.out.println(儿子在玩耍); } }输出结果回到开头的注册系统正是因为用了多态我们只写了一个 register(Person p) 方法就能处理所有类型的人员注册。如果不用多态Student、Teacher、Admin 各写一个方法代码会臃肿成什么样这只是一个小例子在日常开发中我们也会用很多使用多态的场景。希望可以帮助你理解多态。