Java多态遇到泛型类型

1.数组参数的多态化

(1):实例1

class Animal
{
	void eat()
	{
		System.out.println("animal is sleeping");
	}
}

class Dog extends Animal
{
	void bark()
	{
		System.out.println("dog is barking");
	}
}

class Cat extends Animal
{
	void meow()
	{
		System.out.println("cat is meowing");
	}
}

class HelloWorld
{
	public static void main(String[] args)
	{
		Animal[] animals = {new Dog(),new Dog(),new Dog()};
		takingAnimals(animals);
	
	}
	
	public static void takingAnimals(Animal[] animals)
	{
		animals[0] = new Cat();
	}
}

编译和运行都可以通过


(2)实例2:

class Animal
{
	void eat()
	{
		System.out.println("animal is sleeping");
	}
}

class Dog extends Animal
{
	void bark()
	{
		System.out.println("dog is barking");
	}
}

class Cat extends Animal
{
	void meow()
	{
		System.out.println("cat is meowing");
	}
}

class HelloWorld
{
	public static void main(String[] args)
	{
		
		Dog[] dogs = {new Dog(),new Dog()};
		takingAnimals(dogs);
	}
	
	public static void takingAnimals(Animal[] animals)
	{
		animals[0] = new Cat();
	
	}
}
编译的时候不会出错,但运行的时候会出错,这是因为数组类型是在运行期间检查的,运行期间检查到animlas[0]是Dog类型,将Cat类型的实例赋给它,会报错


2.将上面的数组array换成列表ArrayList时:

集合参数的多态化:

(1)实例1:

class Animal
{
	void eat()
	{
		System.out.println("animal is sleeping");
	}
}

class Dog extends Animal
{
	void bark()
	{
		System.out.println("dog is barking");
	}
}

class HelloWorld
{
	public static void main(String[] args)
	{
		ArrayList<Animal> animals = new ArrayList<Animal>();
		animals.add(new Dog());
		animals.add(new Dog());
		takingAnimal(animals);
	}
	
	public static void takingAnimal(ArrayList<Animal> animals)
	{
		for(Animal a:animals)
		{
			a.eat();
		}
	}
}
编译可以通过,运行也可以通过


(2)实例2:

如果传入takingAnimal方法的是Dog类型的列表

class Animal
{
	void eat()
	{
		System.out.println("animal is sleeping");
	}
}

class Dog extends Animal
{
	void bark()
	{
		System.out.println("dog is barking");
	}
}

class HelloWorld
{
	public static void main(String[] args)
	{
		ArrayList<Dog> dogs = new ArrayList<Dog>();
		dogs.add(new Dog());
		dogs.add(new Dog());
		takingAnimal(dogs);
	}
	
	public static void takingAnimal(ArrayList<Animal> animals)
	{
		for(Animal a:animals)
		{
			a.eat();
		}
	}
}

      编译器无法通过,编译器不让通过是为了避免下面的情况,若传入 takeAnimals方法的是Dog类型的列表dogs,这时无法将一只猫添加进dogs列表中,为什么上面的数组可以编译通过呢,这是因为数组的类型是在运行期间检查的,而集合的类型检查只会 发生在编译期间

public void takeAnimals(ArrayList<Animal> animals)
{
	animals.add(new Cat());
}


3.多态化集合参数的办法 :有一种能够创建出接收Animal子型参数的方法,就是使用万用字符,万字符有两种语法形式

 第一种语法:

	public static void takingAnimal(ArrayList<? extends Animal> animals)
	{
		for(Animal a: animals)
		{
			a.eat();
		}
	}
第二种语法:

	public static<T extends Animal> void takingAnimal(ArrayList<T> animals)
	{
		for(Animal a: animals)
		{
			a.eat();
		}
	}

     使用万用符的好处:传入takingAnimal方法的可能还是dogs列表,这样dogs列表里面还是可能被加进去Cat类型的实例,但实际上使用带有<?>的声明时,编译器不会允许加入任何东西到集合中。 


4.两者的对比

public static void takingAnimal(ArrayList<Animal> animals)
与public static void takingAnimal(ArrayList<? extends Animal> animals)的对比

 <? extends Animal>表示任何Animal和Animal的子型都是合法的,可以输入ArrayList<Dog>,ArrayList<Cat>,ArrayList<Animal>类型的参数

ArrayList<Animal> animals 表示只有ArrayList<Animal>类型是合法的


5.练习:

ArrayList<Dog> dog1 = new ArrayList<Animal>();
错误  说明:这个都不是多态,显然错误

ArrayList<Animal> animals = new ArrayList<Dog>();
错误  说明:正如上面分析的,集合的类型检查会在编译期间,编译器不会允许这种形式的多态,将一个Dog类型的列表赋给Animal类型列表

List<Animal> animals = new ArrayList<Animal>();
正确 说明:ArrayList实现了List接口

ArrayList<Dog> dogs = new ArrayList<Dog>();
正确 说明:声明了一个Dog类型的列表dogs

ArrayList<Animal> animals = dogs;
错误 说明:正如上面分析的,集合的类型检查会在编译期间,编译器不会允许这种形式的多态,将一个Dog类型的列表赋给Animal类型列表




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值