多态性是OOP中的一个重要特性,主要是用来实现动态联编的,换句话说,就是程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。这对于大型系统来说能提高系统的灵活性和扩展性。
java中如何实现多态?使用多态的好处?
引用变量的两种类型:
编译时类型(模糊一点,一般是一个父类)
由声明时的类型决定。
运行时类型(运行时,具体是哪个子类就是哪个子类)
由实际对应的对象类型决定。
多态的存在要有3个必要条件:
①要有继承②要有方法重写③父类引用指向子类对象
1.1多态的概述
同一个对象,在不同时刻表现出来的不同形态
举例:猫
我们可以说猫是猫:猫 cat = new 猫();
我们也可以说猫是动物:动物 animal = new 猫();
这里猫在不同的时刻表现出来了不同的形态,这就是多态
1.2多态的前提和体现
①有继承/实现关系
②有方法重写
③有父类引用指向子类对象
1.3多态的好处和弊端
多态的好处:提高了程序的扩展性
具体体现:定义方法的时候,使用父类作为参数,将来在使用的时候,使用具体的子类型参与操作
多态的弊端:不能使用子类的特有功能
1.4多态中的转型
①向上转型
从子到父
父类引用指向子类对象
②向下转型
从父到子
父类引用转为子类对象
多态:
对应同一个指令(调用同一个名称的方法),不同的对象给予不同的反应(不同的方法实现)
规范(多态实现的前提):
1、必须要有继承关系
2、子类方法必须重写父类的方法
3、父类引用指向子类对象(子类实例)
多态的目的:
1、为了提高代码的扩展性和维护性
2、方便代码逻辑的编写
多态的两种表现形式:
1、父类作为方法的参数
2、父类作为方法的返回值类型
引用类型的转换跟基本数据类型的转换类似:
1、当父类需要转成子类的时候,要进行强制转换,但是在强制转换之前一定要先判断父类引用指向的子类对象到底是谁,
如果无法确定,在运行过程中可能出错
2、当子类需要向父类转换的时候,直接自动转换,不需要进行任何的判断。
多态示例代码
package object;
public class TestPolym {
class Animal {
int age=10;
public void shout(){
System.out.println("叫了一声!");
public static void main(String[] args) {
Animal animal = new Dog(); //向上可以自动转型
System.out.println(animal.age); //属性调用时,仍然是基类的属性
}
// animal.shout();
}
class Dog extends Animal {
int age=28;
animalCry(new Dog());
//传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。
//如果没有多态,我们这里需要写很多重载的方法。如果增加一种动物,就需要 public void shout() {
System.out.println("旺旺旺!");
}
//有了多态,只需要增加这个类继承Animal基类就可以了。
animalCry(new Cat());
Dog dog = (Dog) animal; //编写程序时,如果想调用运行时类型的方法
dog.gnawBone();
System.out.println(dog instanceo
System.out.println(animal instanceof Cat);
System.out.println(animal instanceof Dog);
public void gnawBone(){
System.out.println(“我在啃骨头");
}
}
}
class Cat extends Animal {
int age=18;
public void shout() {
System.out.println("喵喵喵喵!");
}
static void animalCry(Animal a){
a.shout();
}
}
练习
(父类)Pet类.java
public abstract class Pet {
int health;
int love;
public abstract void play();
}
(子类)Penguin类.java
public class Penguin extends Pet {
@Override
public void play() {
System.out.println("企鹅正在陪主人玩躲猫猫游戏,健康值+10,亲密度+10");
}
}
(子类)Dog类.Java
public class Dog extends Pet{
@Override
public void play(){
System.out.println("小狗正在跟主人玩接飞盘游戏,健康值+15,亲密度+5");
}
}
主人类 Person.java
public class Person{
public void play(Pet pet){
pet.play();
}
public Pet getPet(String typeId){
if(typeId.equals("0")){
return new Dog();
}else{
return new Penguin();
}
}
public static void main(String[] args) {
Person person =new Person();
Pet dog = new Dog();
person.play(dog);
dog.play();
Pet penguin = new Penguin();
Pet pet =person.getPet("0");
if(pet instanceof Dog){
System.out.println("领养的是狗");
}else if(pet instanceof Penguin){
System.out.println("领养的是企鹅");
}
}
}
instanceof运算符
-对象 instanceof 类或接口
-instanceof通常和强制类型转换结合使用
Pet.java
public abstract class Pet {
public abstract void feed();
public void show(){
System.out.println("show... ...");
}
}
Dog.java
public class Dog extends Pet{
@Override
public void feed() {
System.out.println("狗在吃骨头... ...");
}
public void test(){
System.out.println("test... ...");
}
}
Penguin.java
public class Penguin extends Pet{
@Override
public void feed() {
System.out.println("企鹅正在吃鱼... ...");
}
Cat.java
public class Cat extends Pet{
@Override
public void feed() {
System.out.println("猫正在吃猫粮... ...");
}
Person.java
public class Person{
public void feed(Pet pet){
pet.feed();
}
public Pet getPet(String typeId){
if(typeId.equals("0")){
return new Dog();
}else if(typeId.equals("1")){
return new Penguin();
}else{
return new Cat();
}
}
public static void main(String[] args) {
Person person = new Person();
Pet dog = new Dog();
person.feed(dog);
dog.show();
Pet penguin = new Penguin();
person.feed(penguin);
Cat cat = new Cat();
person.feed(cat);
Pet pet = person.getPet("0");
if(pet instanceof Dog){
System.out.println("领养的是狗");
}else if(pet instanceof Penguin){
System.out.println("领养的是企鹅");
}else if(pet instanceof Cat){
System.out.println("领养的是猫");
}
}
}
引用数据类型的类型转换
▪ 子类转换为父类:自动转换
– 上转型对象不能操作子类新增的成员变量和方法。
– 上转型对象可以操作子类继承或重写的成员变量和方法
– 如果子类重写了父类的某个方法,上转型对象调用该方法时,是调用的重写
方法。
▪ 父类转换为子类:强制转换
– (绝不是做手术,而是父类的真面目就是一个子类,否则会出现类型转换错
误)
小结
类型转换
-向上转型——子类转换为父类,自动进行类型转换
-向下转型——父类转换为子类,结合instanceof运算符进行强制类型转换
实现多态的两种方式
-使用父类作为方法形参实现多态
-使用父类作为方法返回值实现多态
使用多态的好处?
-多态可以减少类中代码量,可以提高代码的可扩展性和可维护性
引用变量的两种类型:
-编译时类型(模糊一点,一般是一个父类)
由声明时的类型决定。
-运行时类型(运行时,具体是哪个子类就是哪个子类)
由实际对应的对象类型决定。
多态的存在要有3个必要条件:
①要有继承②要有方法重写③父类引用指向子类对象