package dd20161114_2;
/**
父类pet
*/
public class Pet {
public void eat() {
System.out.println("吃饭");
}
}
package dd20161114_2;
public class Dog extends Pet {
public void eat() {
// TODO Auto-generated method stub
System.out.println("狗啃骨头");
this.hight=5;
}
}
package dd20161114_2;
public class Cat extends Pet{
public void eat() {
// TODO Auto-generated method stub
System.out.println("猫吃鱼");
}
}
三个类,Dog和Cat分别继承了Pet类
package dd20161114_2;
public class Master1 {
public static void main(String[] args) {
//dog对象实例化
Dog dog=new Dog();
eat(dog);
//cat对象实例化
Cat cat=new Cat();
eat(cat);
//Pet对象实例化
Pet pet=new Dog();
pet=new Cat();
eat(pet);
}
public static void eat(Pet pet){
pet.eat();
}
}
输出结果:
狗啃骨头
猫吃鱼
猫吃鱼
从输出结果中可以看出,eat方法需要传递的参数为Pet的一个对象,但是当我传递它的子类的时候也可以,而且调用了相应的方法。我还可以通过实例化子类对象获得父类声明的对象,调用方法的时候它会自动去找对应子类的方法,这就是对象的向上转型和向下转型
父类对象通过子类对象去实例化,实际上就是对象的向上转型。向上转型是不需要进行强制类型转换的,但是向上转型会丢失精度。
所谓向下转型,也就是说父类的对象可以转换为子类对象,但是需要注意的是,这时则必须要进行强制的类型转换。
子代父类实例化,然后就相当于一个父亲有很多儿子,送快递的给这个父亲的儿子送东西,他只需要送到父亲的家就行了,至于具体是那个儿子的,父亲还会分不清自己的儿子么,所以你就不用操心了。
多态方式声明是一种好的习惯。当我们创建的类,使用时,只用到它的超类或接口定义的方法时,我们可以将其索引声明为它的超类或接口类型。
它的好处是,如果某天我们对这个接口方法的实现方式变了,对这个接口又有一个新的实现类,我们的程序也需要使用最新的实现方式,此时只要将对象实现修改一下,索引无需变化。
比如Map< String,String> map = new HashMap < String,String>();想换成HashTable实现,可以Map< String,String> map = new HashTable < String,String>();
比如写一个方法,参数要求传递List类型,你就可以用List list = new ArrayList()中的list传递,但是你写成ArrayList list = new ArrayList()是传递不进去的。尽管方法处理时都一样。另外,方法还可以根据你传递的不同list(ArrayList或者LinkList)进行不同处理。
在Java编程思想这本书中有介绍