10 面向对象三大特性之多态

面向对象三大特性之多态

多态的概念

概念:多态就是父类引用指向子类对象
满足: dog is  a  animal

现实生活中 一个事物是什么  取决于你认为他是什么

你认为是什么---  Animal a   引用
这个事物真实存在的是什么类型-----对象  

继承是多态的前提!!!!

多态的特点

编译时多态(还没有打开箱子 无法确定箱子中所放的数据类型)
特点:在编译时只能通过引用调用引用所对应类中声明的方法
编译时编译器无法确定引用中所放的数据是什么类型
案例:
public class Demo{
	public static void main(String[] args) {
		//java 是强类型语言   
		//Dog d = new Dog();
		Animal a = new Dog();
		a.eat();
		a.sleep();	

		//a.shout();//编译报错
	}
	
}

class  Animal{
	//吃
	public void eat(){
		System.out.println("动物吃");
		
	}
	//睡
	public void sleep() {
		System.out.println("动物睡");
	}
}

class Dog extends Animal{

	//加
	public void shout() {
		System.out.println("狗叫");
		
	}

}


验证编译器是否能确定引用中所放的数据类型
代码:
import java.util.*;
public class Demo{
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		System.out.println("请输入一个整数:");
		int i = s.nextInt();
		Animal a;
		if (i%2==0) {
			a = new Dog();
		} else {
			a = new ShiKeLang();
		}	
	}
}

class  Animal{
	//吃
	public void eat(){
		System.out.println("动物吃");
		
	}
	//睡
	public void sleep() {
		System.out.println("动物睡");
		
	}
	
	
}


class Dog extends Animal{

	//加
	public void shout() {
		System.out.println("狗叫");
		
	}

	
}

class ShiKeLang extends Animal{
	public void moveShi() {
		System.out.println("移动屎球");
		
	}
	
	
}
运行时多态(打开箱子 能够确定数据类型了 )
特点:当多态发生时,运行代码时调用的是子类覆盖父类后的方法的实现
案例:
import java.util.*;
public class Demo{
	public static void main(String[] args) {
		Animal a = new Dog();

		a.eat();
		a.sleep();
	}
}

class  Animal{
	//吃
	public void eat(){
		System.out.println("动物吃");
		
	}
	//睡
	public void sleep() {
		System.out.println("动物睡");
	}
}


class Dog extends Animal{
	//吃
	public void eat(){
		System.out.println("狗吃屎");
		
	}
	//睡
	public void sleep() {
		System.out.println("狗趴着睡");
	}
	//加
	public void shout() {
		System.out.println("狗汪汪的叫");
	}
}

class ShiKeLang extends Animal{
	public void moveShi() {
		System.out.println("移动屎球");	
	}
}

关于属性是否有多态

属性是不存在多态的
案例:
import java.util.*;
public class Demo{
	public static void main(String[] args) {
		Animal a = new Dog();

		System.out.println(a.name);	//动物
	}
}

class  Animal{
	String name = "动物";
	//吃
	public void eat(){
		System.out.println("动物吃");
	}
	//睡
	public void sleep() {
		System.out.println("动物睡");	
	}
}


class Dog extends Animal{
	String name = "哈士奇";
	//吃
	public void eat(){
		System.out.println("狗吃屎");
	}
	//睡
	public void sleep() {
		System.out.println("狗趴着睡");	
	}
	//加
	public void shout() {
		System.out.println("狗汪汪的叫");
	}
}

class ShiKeLang extends Animal{
	public void moveShi() {
		System.out.println("移动屎球");
		
	}
	
	
}

引用之间的转换

向上转型
将子类对象的引用赋值给父类类型的引用
案例:
import java.util.*;
public class Demo{
	public static void main(String[] args) {
		Dog d = new Dog();

		Animal a = d;	
	}
}

class  Animal{
	String name = "动物";
	//吃
	public void eat(){
		System.out.println("动物吃");
	}
	//睡
	public void sleep() {
		System.out.println("动物睡");
	}	
}


class Dog extends Animal{
	String name = "哈士奇";
	//吃
	public void eat(){
		System.out.println("狗吃屎");
	}
	//睡
	public void sleep() {
		System.out.println("狗趴着睡");
	}
	//加
	public void shout() {
		System.out.println("狗汪汪的叫");
	}	
}

class ShiKeLang extends Animal{
	public void moveShi() {
		System.out.println("移动屎球");
	}
}
向下转型
将父类类型的引用赋值给子类类型的引用
意义:当我们需要用父类的引用去调用子类特有的方法时,需要将父类的引用类型向下转型为子类类型的引用,这时候需要强制转换,结果可能失败  会报类型转换异常
Exception in thread "main" java.lang.ClassCastException: ShiKeLang cannot be cast to Dog    at Demo.main(Demo.java:5)
从以上的案例说明:一个对象创建之后 其类型永远不可改变(java中对象类型不可变)

案例:
import java.util.*;
public class Demo{
	public static void main(String[] args) {
		Animal a = new ShiKeLang();
		Dog d = (Dog)a;	

		d.shout();
		
	}
}

class  Animal{
	String name = "动物";
	//吃
	public void eat(){
		System.out.println("动物吃");
	}
	//睡
	public void sleep() {
		System.out.println("动物睡");
	}
}


class Dog extends Animal{
	String name = "哈士奇";
	//吃
	public void eat(){
		System.out.println("狗吃屎");
	}
	//睡
	public void sleep() {
		System.out.println("狗趴着睡");
	}
	//加
	public void shout() {
		System.out.println("狗汪汪的叫");
	}
}

class ShiKeLang extends Animal{
	public void moveShi() {
		System.out.println("移动屎球");
	}
}
当两个类之间没有继承关系 这两个类引用之间是否可以转换
当两个类之间没有继承关系时 引用类型之间是不可以转换的   即使强制转换 编译也不通过
案例:
import java.util.*;
public class Demo{
	public static void main(String[] args) {
		ShiKeLang s = new ShiKeLang();

		Dog d = (Dog)s;
		
	}
}

class  Animal{
	String name = "动物";
	//吃
	public void eat(){
		System.out.println("动物吃");
	}
	//睡
	public void sleep() {
		System.out.println("动物睡");
		
	}
}


class Dog extends Animal{
	String name = "哈士奇";
	//吃
	public void eat(){
		System.out.println("狗吃屎");
	}
	//睡
	public void sleep() {
		System.out.println("狗趴着睡");
	}
	//加
	public void shout() {
		System.out.println("狗汪汪的叫");
	}
}

class ShiKeLang extends Animal{
	public void moveShi() {
		System.out.println("移动屎球");	
	}
}

instanceof(实例 属于)

作用:能够判断一个引用中所存放的数据类型
语法:
引用名  instanceof 类型

a instanceof  Dog

值是一个布尔类型
案例:
import java.util.*;
public class Demo{
	public static void main(String[] args) {
		Animal a = new Dog();
		if (a instanceof Dog) {
			Dog d = (Dog)a;
			d.shout();
		} else {
			a.eat();
			a.sleep();
		}
	}
}

class  Animal{
	String name = "动物";
	//吃
	public void eat(){
		System.out.println("动物吃");
	}
	//睡
	public void sleep() {
		System.out.println("动物睡");
		
	}
}


class Dog extends Animal{
	String name = "哈士奇";
	//吃
	public void eat(){
		System.out.println("狗吃屎");
	}
	//睡
	public void sleep() {
		System.out.println("狗趴着睡");
	}
	//加
	public void shout() {
		System.out.println("狗汪汪的叫");
	}
}

class ShiKeLang extends Animal{
	public void moveShi() {
		System.out.println("移动屎球");
	}
}


案例:
Animal a = new ShiKeLang();
System.out.println(a instanceof Dog );//false

ShiKeLang a = new ShiKeLang();
System.out.println(a instanceof Dog );//编译报错

在用instanceof判断之前首先编译器会先进行判断两个类之间是否存在继承关系

关于多态中的特点的口诀

编译看左边:编译时 只能调用引用所对应类中声明的方法
运行看右边:当多态发生时 调用方法执行的是子类覆盖父类后的方法的实现

Animal a  = new Dog();

多态的应用

多态用在数组中
定义一个动物类
	方法: eat()
每个子类都重写eat方法
狗类
猫类


案例:
public class Demo{
	public static void main(String[] args) {
		//分别创建每个子类的对象 调用吃的方法
		/*Dog d = new Dog();
		Cat c = new Cat();

		d.eat();
		c.eat();*/

		//数组将这些动物
		Animal[] zoo = {new Dog(),new Cat()};

		//遍历
		for(int i = 0;i<zoo.length;i++) {
			zoo[i].eat();
		} 		
	}
}
class Animal{
	//吃
	public void eat() {
		System.out.println("动物吃");
	}
}

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

class Cat extends Animal{
	public void eat() {
		System.out.println("猫吃鱼");
	}
}

练习:
有一个动物类的数组 数组中有很多动物对象  统计数组中狗对象的个数
考点:
instanceof

升级:将所有的狗对象放到一个狗窝中(狗的数组)

public class Demo{
	public static void main(String[] args) {
		//分别创建每个子类的对象 调用吃的方法
		/*Dog d = new Dog();
		Cat c = new Cat();*/

		//数组将这些动物
		Animal[] zoo = {new Dog(),new Cat(),new Dog(),new Cat()};
		int sum = 0;
		for(int i = 0;i<zoo.length;i++) {
			//判断是否为狗
			if (zoo[i] instanceof Dog) {
				sum++;
			} 		
		} 

		System.out.println(sum);

		Dog[] d = new Dog[sum];
		int j = 0;
		for(int i = 0;i<zoo.length;i++) {
			if (zoo[i] instanceof Dog) {
				d[j] = (Dog)zoo[i];
				j++;
			} 
		} 		
	}
}


class Animal{
	//吃
	public void eat() {
		System.out.println("动物吃");
	}
}

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

class Cat extends Animal{
	public void eat() {
		System.out.println("猫吃鱼");
	}	
}

改进之后的案例:

import java.util.*;
public class Demo{
	public static void main(String[] args) {
		//分别创建每个子类的对象 调用吃的方法
		/*Dog d = new Dog();
		Cat c = new Cat();*/

		//数组将这些动物
		Animal[] zoo = {new Dog(),new Cat()};
		Dog[] d = new Dog[0];
		int j = 0;
		for(int i = 0;i<zoo.length;i++) {
			//判断是否为狗
			if (zoo[i] instanceof Dog) {
				d = Arrays.copyOf(d,d.length+1);
				d[j] = (Dog)zoo[i];
				j++;
			} 		
		} 
		System.out.println(d.length);	
	}
}
多态用在函数的参数上
案例: 多态可以使函数的功能更加通用  
import java.util.*;
public class Demo{
	public static void main(String[] args) {
	
		m(new Dog());
		m(new Cat());
		m(new Duck());
			
	}
	//给我传进一个动物  我会调用这个动物吃的方法 Animal a = new Dog()
	public static void m(Animal a) {
		a.eat();	
	}
}


class Animal{
	//吃
	public void eat() {
		System.out.println("动物吃");
	}	
}

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

class Cat extends Animal{
	public void eat() {
		System.out.println("猫吃鱼");
	}
}
多态用在函数的返回值上
马戏团中有好多动物  游客可以买票看不同的动物

10  ------20 ------30 ----40-----1000--- 老虎

参数:double d 
返回值类型:Animal    return new Dog();

案例:
import java.util.*;
public class Demo{
	public static void main(String[] args) {
		Animal a = sh
	}

	public static Animal showAnimal(double d) {
		if (d==10) {
			return new Fish();
		} else if (d==20) {
			return new Monkey();
		} else if (d==30) {
			return new Sheep();
		} else if (d==40) {
			return new Dog();
		} else if (d==1000) {
			return new Tiger();
		} else{
			return null;
		}	
	}	
}


class Animal{
	//吃
	public void eat() {
		System.out.println("动物吃");
	}	
}

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

class Cat extends Animal{
	public void eat() {
		System.out.println("猫吃鱼");
	}
}

class Monkey extends Animal{
	public void eat() {
		System.out.println("猴子吃桃");	
	}
}
class Tiger extends Animal{
	public void eat() {
		System.out.println("老虎吃人");		
	}
}

class Sheep extends Animal{
	public void eat() {
		System.out.println("羊吃草");
	}	
}
class Fish extends Animal{
	public void eat() {
		System.out.println("鱼吃虾米");	
	}
}

class Duck extends Animal{
	public void eat() {
		System.out.println("鸭子嘎嘎的吃");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值