Java中的多态

多态:可以理解为事物存在的多种体现形态。再设计一个方法时,通常希望该方法具备一定的通用性。例如要实现一个动物叫的方法,由于每种动物的叫声不同,因此可以在方法中定义一个接收动物类型的参数。当传入猫类对象时,运行猫叫的方法,传入狗类对象时就运行狗叫的方法。在同一个方法中,这种由于参数类型不同而引起的执行效果不同的现象就是多态。

多态实现的三个必要条件:
一、要有继承; 
二、要有重写; 
三、父类引用指向子类对象。

Java中多态的实现方式:

1. 接口实现    :一个类实现多个接口。(常用)

2. 继承父类进行方法重写    :多个子类重写父类方法,并且各子类的方法体不同

3. 同一个类中进行方法重载    :一个方法由于参数类型和个数不同,重载出多个函数实现多个功能。

4. 父类引用子类对象     :将子类向上转型(转成父类),利用父类引用,可以同时操作多种不同对象。(常用)

父类引用的格式:


在多态中成员函数的特点:
Fu f = new zi();
f.方法1;
f.方法2;
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过。
如果没有,则编译失败。
在运行期间:参阅对象所属的类中是否有调用的方法,有就运行,没有就运行错误。
简单来说:成员函数在多态调用时,编译看左边运行看右边。

在多态中成员变量的特点:
无论编译还是运行,都参考左边(引用型变量所属的类)

在多态中静态成员函数的特点:
无论编译还是运行,都参考左边(引用型变量所属的类)
也就是说父类引用不能访问子类成员变量,不然会报错。


注意:多态的弊端:只能使用父类的引用去访问父类中的成员,如需使用子类成员强制将父类引用转成子类类型。

 

 

例一:接口实现

//定义一个人抽烟的接口
interface Smoke{
    public String smoking();
}

//定义一个人喝酒的接口
interface Drink{
    public String drinking();
}

//定义Person类
class Person{
    
    Person(String a){
        name = a;
    }
    String name;

void speak(){
    System.out.println("my name is "+ name);
    }

}

//定义一个子类,既抽烟又喝酒的人
class Person1 extends Person implements Smoke,Drink{
 
super("张三");//当实例化多个对象时 super的参数可以手动输入

public String smoking(){
    return "抽烟";
    }



public String drinking(){
    return "喝酒";
    }


void speak(){
    System.out.println("my name is "+ this.name+". I like "+ smoking()+" and " + drinking());
    }

}

class Runing{
public static void main(String[] args){
    Person1 p = new Person1();
    p.speak();
    }

}

/*
运行结果:
my name is 张三. I like 抽烟 and 喝酒
*/



例二.继承父类重写方法

//定义抽象类
 
abstract class Animal{
   
 //定义抽象方法
 
    abstract void shut();
}
 
//继承于Animal的猫类
class Cat extends Animal{
    //重写父类的shut()方法
    void shut(){
    System.out.println("喵喵......");
    }
}
 
 
//继承于Animal的狗类
class Dog extends Animal {
    //重写shut()方法
    void shut(){
    System.out.println("汪汪......");
    }
}
 
 
class RunAnimal{
    public static void main(String[] args){
    Cat c = new Cat();
    Dog d = new Dog();
    
    c.shut();
    d.shut();
    }
 
}

/*
运行结果:
喵喵......
汪汪......
*/

例三:重载

class Demo {



        void speak(){
            System.out.println("1");
        }



        int speak(int a){
            int b = a;
            return b;
        }


        int speak(int a,int b){
            int c = a;
            int d = b;  
        }
        
    
}



class Runing{
    public static void main(String[] args){
        Demo d = new Demo();
        d.speak();                           //调用无参speak函数
        System.out.println();
        System.out.println(d.speak(3));     //调用有一个参数的speak函数
        System.out.println(d.speak(4,5));    //调用有两个参数的speak函数
    }

}

/*
运行结果:
1
3
5
*/

例四:父类引用

/*需求:
主板上有两个PCI接口,PCI接口可以插网卡或者声卡等
模拟主板运行,程序要有扩展性
*/

interface PCI{
	public void open();
	public void close();
	
}

interface PCI1 extends PCI{
	
}
interface PCI2 extends PCI{
	
}

class Mainboard {

	public void open(){
		System.out.println("主板运行");
	}

	public void close (){
		System.out.println("主板关闭");
	}
	
    //定义方法用来主板使用网卡声卡等
	public void usePCI(PCI c){
		c.open();
	}
	
	
	public void closePCI(PCI c){
		c.close();
	}
	
}


//声卡使用PCI1接口
class Voiceboard implements PCI1{
	public void open(){
		System.out.println("Voiceboard run");
	}
	public void close (){
		System.out.println("Voiceboard close");
	}
	
}
//网卡使用PCI2接口
class Netboard implements PCI2{
	public void open(){
		System.out.println("netceboard run");
	}
	public void close (){
		System.out.println("netceboard close");
	}
}




class Runing{
	public static void main(String[] args){
		Mainboard M1 = new Mainboard();
        M1.open();
		Voiceboard v = new Voiceboard();
		M1.usePCI(v);
		//等价于 M1.usePCI(new Voiceboard()); 
		Netboard n = new Netboard();
		M1.usePCI(n);
		//M1.usePCI(new Netboard());
		System.out.println("使用一段时间后...\n主板即将关闭......");
		M1.closePCI(v);
		M1.closePCI(n);
		M1.close();
	}
	
	
	
}
/*
运行结果:
主板运行
Voiceboard run
netceboard run
使用一段时间后...
主板即将关闭......
Voiceboard close
netceboard close
主板关闭
*/

父类引用,运行期间执行的是对象的父类中被复写过的子类方法。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值