java上转型对象详解

class Father {
    
    
	String Fname = "爸爸";
	public void sleep() {
    
    
		//睡觉方法
		System.out.println(Fname + "睡觉");
	}
}

class Son extends Father {
    
    
	String Sname = "儿子";
	public void p() {
    
    
		//调皮方法
		System.out.println(Sname + "调皮");
	}
}

public class Test {
    
    
	public static void main(String[] args) {
    
    
		Father f= new Son();
		f.sleep();
		System.out.println(f.Fname);
		//System.out.println(f.Sname);   编译器报错
		//f.p();   编译器报错
		
		System.out.println();
		System.out.println(((Son)f).Fname);
		System.out.println(((Son)f).Sname);
		((Son)f).sleep();
		((Son)f).p();;
	}
}
//程序输出结果为
//  			爸爸睡觉
//				爸爸
//
//				爸爸
//				儿子
//				爸爸睡觉
//				儿子调皮

当一个父类的对象引用的是子类的实例时,我们可以把这个父类对象叫做上转型对象。
这里有两种方法创建上转型对象

1.Father f= new Son();
2.Son son= new Son();
Father f=(Father)son;

Son是Father的子类,f就是上转型对象
(1)上转型对象不能操作子类声明定义的成员变量(失掉了这部分属性),不能使用子类声明定义的方法(失掉了一些功能)。这里f失去了Sname这个成员变量,失去了P这个方法,可以看作是一种”瘦身”。
(2)上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法

(3)可以将上转型对象再强制转换成子类对象,这样,该子类对象又具备了子类具有所有属性和方法。

(4)如果子类重写了父类的某个方法后,当对象的上转型对象调用这个方法时一定是调用了这个重写的方法。这里我们再展开来讲一下,我们给Father类和Son类分别添加speak方法

class Father {
    
    
	String Fname = "爸爸";
	public void sleep() {
    
    
		//睡觉方法
		System.out.println(Fname + "睡觉");
	}
	public void speak() {
    
    
		System.out.println("我是爸爸");
	}
}

class Son extends Father {
    
    
	String Sname = "儿子";
	public void p() {
    
    
		//调皮方法
		System.out.println(Sname + "调皮");
	}
	public void speak() {
    
    
		System.out.println("我是儿子");
	}
}

public class Test {
    
    
	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		Father f= new Son();
		f.speak();
		//调用子类重写的方法
		
		System.out.println();
		((Son)f).speak();
	}
}
//程序输出结果为:
//				我是儿子
//
//				我是儿子   

Son重写了Father类的speak方法,上转型对象调用的是son类的speak方法,所以输出”我是儿子”。

接下来,我们就需要了解上转型对象的实现意义,为什么 java开发人员要设计一个上转型对象呢。

class Animal {
    
    
	void cry() {
    
    
	}
}

class Dog extends Animal {
    
    
	void cry() {
    
    
		System.out.println("汪汪");
	}
}

class Cat extends Animal {
    
    
	void cry() {
    
    
		System.out.println("喵喵");
	}
}

public class 上转型对象多态 {
    
    
	public static void beat(Dog dog) {
    
    
		System.out.println("打了它一下");
		dog.cry();
	}
	public static void beat(Cat cat) {
    
    
		System.out.println("打了它一下");
		cat.cry();
	}
	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		Dog dog= new Dog();
		Cat cat= new Cat();
		beat(dog);
		beat(cat);
	}
}
//程序输出结果:
//		打了它一下
//		汪汪
//		打了它一下
//		喵喵

这里我们没有使用上转型对象,beat方法写了两种。

public class 上转型对象多态 {
    
    
	public static void beat(Animal animal) {
    
    
		System.out.println("打了它一下");
		animal.cry();
	}
	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		Dog dog= new Dog();
		Cat cat= new Cat();
		beat(dog);
		beat(cat);
	}
}
//程序输出结果:
//		打了它一下
//		汪汪
//		打了它一下
//		喵喵

      原来需要写两个beat函数才能实现的功能,现在只需写一个就行了
      我们使用了上转型对象,上转型对象调用子类重写的方法,实现了方法的多态,还降低了程序之间关联性。
      比如说我现在想要再写一个Animal类的子类,如果不用上转型对象,那我还要再添加一个beat方法,但是有了上转型对象,Animal的子类想怎么添加,怎么添加,beat方法到最后都可以使用。

      同时,我们还注意到,上转型对象会调用子类重写的方法,父类隐藏的那个方法永远都用不到。上面的例子中Cat和Dog重写了Animal的cry()方法,Animal中的cry()的方法体是什么根本无所谓。Java开发人员想了想,反正隐藏的方法体是什么无所谓,要不我们直接定义一个结构,方法只可以声明(没有方法体)。于是这样,抽象类就被发明了。后来,由于java只支持单继承,抽象类有时不能满足开发需求,开发人员又发明了接口,接口可以实现多重继承,一个类可以实现多个接口。
      面向对象编程,代码多态和复用的思想贯串始终。这种编程思想真的非常好,极大的降低了程序之间的关联性

==============================================================================
参考博客:
Java向上转型和向下转型的通俗简单理解以及使用用途
Java向上转型的作用(有详细代码介绍)
这边还有一个解释抽象类和接口区别的深度好文,大家也可以看看:
Java 接口(interface)的用途和好处

猜你喜欢

转载自blog.csdn.net/cookie_plus/article/details/107244196
今日推荐