java之 多态-扩展性、多态子父类的类型转换、equals方法

多态:可以理解为事物存在的多种体现形态。

人:男人,女人

动物:猫,狗。

猫 x = new 猫();

动物 x = new 猫();
1,多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
2,多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。
3,多态的好处
多态的出现大大的提高程序的扩展性。
4,多态的弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。

5,多态的应用

1):多态可扩展性

观察如下给出几个程序,可以看出多态的好处(可扩展性)

abstract class Animal
{
	abstract void eat();

}

class Cat extends Animal
{
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal
{
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}

class DuoTaiDemo 
{
	public static void main(String[] args) 
	{
		Cat c = new Cat();
		c.eat();
		Dog d = new Dog();
		d.eat();
	}
}
/*
运行结果:
---------- 运行java ----------
吃鱼
吃骨头

输出完成 (耗时 0 秒) - 正常终止
*/
代码2:

abstract class Animal
{
	abstract void eat();

}

class Cat extends Animal
{
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal
{
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}
class Pig extends Animal

{
	public void eat()
	{
		System.out.println("饲料");
	}
	public void gongDi()
	{
		System.out.println("拱地");
	}
}
class DuoTaiDemo 
{
	public static void main(String[] args) 
	{
		//Cat c = new Cat();
		//c.eat();
		//Dog d = new Dog();
		//d.eat();
		Cat c1 = new Cat();
		fuction(c1);
		fuction(new Dog());
        fuction(new Pig());

	}
	public static void fuction(Cat c)
	{
		c.eat();
	}
	public static void fuction(Dog d)// Dog d = new Dog();
	{
		d.eat();
	}
	public static void fuction(Pig p)//Pig p = new Pig();
	{
		p.eat();
	}

}
/*
运行结果:
---------- 运行java ----------
吃鱼
吃骨头
饲料

输出完成 (耗时 0 秒) - 正常终止
*/
代码3:


abstract class Animal
{
	
	abstract void eat();

}

class Cat extends Animal
{
	
	}
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal
{
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}
class Pig extends Animal

{
	public void eat()
	{
		System.out.println("饲料");
	}
	public void gongDi()
	{
		System.out.println("拱地");
	}
}
class DuoTaiDemo 
{
	public static void main(String[] args) 
	{
		//Cat c = new Cat();
		//c.eat();
		//Dog d = new Dog();
		//d.eat();
		
		//Cat c1 = new Cat();
		//fuction(c1);
		//fuction(new Dog());
        //fuction(new Pig());
		Animal c = new Cat();   //这就是多态的体现 :父类的引用指向了自己的子类的对象
		c.eat();
		
		
	}
	public static void fuction(Cat c)
	{
		c.eat();
	}
	public static void fuction(Dog d)
	{
		d.eat();
	}
	public static void fuction(Pig p)
	{
		p.eat();
	}

}

如上代码中的:
 //fuction(new Pig());
		Animal c = new Cat();   //这就是多态的体现 :父类的引用指向了自己的子类的对象
		c.eat();
		
代码4:

abstract class Animal
{
	abstract void eat();

}

class Cat extends Animal
{
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal
{
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}
class Pig extends Animal

{
	public void eat()
	{
		System.out.println("饲料");
	}
	public void gongDi()
	{
		System.out.println("拱地");
	}
}
class DuoTaiDemo 
{
	public static void main(String[] args) 
	{
		//Cat c = new Cat();
		//c.eat();
		//Dog d = new Dog();
		//d.eat();
		/*
		Cat c1 = new Cat();
		fuction(c1);
		fuction(new Dog());
        fuction(new Pig());
		//Animal c = new Cat();   //这就是多态的体现 :父类的引用指向了自己的子类的对象
		//c.eat();
        function(new Cat());
		function(new Dog());
		function(new Pig());

	}
	public static void function(Animal a)  //相当于内存中:Animal a = new Cat(); 多态的作用:提高了代码的扩展性 
	  // 多态的前提
	  //必须是类与类之间有关系。要么继承,要么实现。
	  //通常还有一个前提:存在覆盖。
	{              
		a.eat();
	}
}
/*运行结果:
---------- 运行java ----------
吃鱼
吃骨头
饲料

输出完成 (耗时 0 秒) - 正常终止
*/

2):多态子父类的类型转换

在编译时期:参阅引用型变量所属的类中是否有调用的方法( 通常就是看等号右边)。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。  (也就是看new 产生的是哪个类的对象  通常就是看等号右边)
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数的特点:无论编译和运行,都参考做左边。

程序1:

如下一个程序要调用子类的catchMouse()方法,而父类没有,所以必须类型转换   ,而调用子类的eat()方法时,编译看左边,父类也有,运行看右边所以调用子类的eat()方法

bstract class Animal
{
	abstract void eat();

}

class Cat extends Animal
{
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal
{
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}
class Pig extends Animal

{
	public void eat()
	{
		System.out.println("饲料");
	}
	public void gongDi()
	{
		System.out.println("拱地");
	}
}
class DuoTaiDemo2 
{
	
	public static void main(String[] args) 
	{
		Animal a = new Cat();//类型提升。 向上转型(子类转父类,子类是属于父类,这里猫属于动物所以,不用强转)。
		a.eat();

		//如果想要调用猫的特有成员时(父类没有而子类特有的),如何操作?
		//强制将父类的引用。转成子类类型。向下转型(父类转子类,)。
		
		Cat c = (Cat)a;
		c.catchMouse();
	}
	public static void function(Animal a)  //相当于内存中:Animal a = new Cat(); 多态的作用:提高了代码的扩展性 
	  // 多态的前提
	  //必须是类与类之间有关系。要么继承,要么实现。
	  //通常还有一个前提:存在覆盖。
	{              
		a.eat();
	}
}
/*
运行结果:
---------- 运行java ----------
吃鱼
抓老鼠

输出完成 (耗时 0 秒) - 正常终止
*/


代码2:

在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)。  所以如下程序中当父类的引用调用age成员属性的时候打印的是父类的age

abstract class Animal
{
	int age = 5;
	abstract void eat();

}

class Cat extends Animal
{   
	int age = 2;
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal
{
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}
class Pig extends Animal

{
	public void eat()
	{
		System.out.println("饲料");
	}
	public void gongDi()
	{
		System.out.println("拱地");
	}
}
class DuoTaiDemo2 
{
	
	public static void main(String[] args) 
	{
		Animal a = new Cat();//类型提升。 向上转型。
		a.eat();
		System.out.println(a.age);

		//如果想要调用猫的特有方法时,如何操作?
		//强制将父类的引用。转成子类类型。向下转型。
		Cat c = (Cat)a;
		c.catchMouse();
	}
	public static void function(Animal a)  //相当于内存中:Animal a = new Cat(); 多态的作用:提高了代码的扩展性 
	  // 多态的前提
	  //必须是类与类之间有关系。要么继承,要么实现。
	  //通常还有一个前提:存在覆盖。
	{              
		a.eat();
	}
}
运行结果:
---------- 运行java ----------
吃鱼
5
抓老鼠

输出完成 (耗时 0 秒) - 正常终止


分析上面代码:
a.eat();  是调用的子类的eat()方法
System.out.println(a.age);打印的是父类的age
*/

代码3:

当转换类型的时候用instanceof判断:

abstract class Animal
{
	abstract void eat();

}

class Cat extends Animal
{
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal
{
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}
class Pig extends Animal

{
	public void eat()
	{
		System.out.println("饲料");
	}
	public void gongDi()
	{
		System.out.println("拱地");
	}
}
class DuoTaiDemo2 
{
	
	public static void main(String[] args) 
	{
		//Animal a = new Cat();//类型提升。 向上转型。
		//a.eat();

		//如果想要调用猫的特有方法时,如何操作?
		//强制将父类的引用。转成子类类型。向下转型。
		//Cat c = (Cat)a;//千万不要出现这样的操作,就是将父类对象转成子类类型。
		//c.catchMouse();//我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。
	                  
	
		function(new Dog());
		function(new Cat());
	}                  
	public static void function(Animal a)  //相当于内存中:Animal a = new Cat(); 多态的作用:提高了代码的扩展性 
	  // 多态的前提
	  //必须是类与类之间有关系。要么继承,要么实现。
	  //通常还有一个前提:存在覆盖。
	{              
		a.eat();
		if( a instanceof Cat)
		{
		Cat c = (Cat)a;
		c.catchMouse();
		}
		else if(a instanceof Dog)
		{
			Dog c = (Dog)a;
			c.kanJia();
		}
	}
}
/*运行结果:
---------- 运行java ----------
吃骨头
看家
吃鱼
抓老鼠

输出完成 (耗时 0 秒) - 正常终止
*/

4)equals()方法

class Demo //extends Object
{
	private int num;
	Demo(int num)
	{
		this.num = num;
	}
public boolean equals(Object obj)//Object obj = new Demo();  
	{

		if(!(obj instanceof Demo))  // 当要比较相不相等 要作一下类型判断
			return false;
		Demo d = (Demo)obj;
       
		return this.num == d.num;
	}	
}
/*	public boolean compare(Demo d)//Object obj = new Demo();   
	{

		

		return this.num == d.num;
	}
}

class ObjectDemo 
{
	public static void main(String[] args) 
	{
		Demo d1 = new Demo(4);
		
		Demo d2 = new Demo(4);  
	
		System.out.println(d1.equals(d2));
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值