父类引用指向子类对象

最近学习装饰者模式的时候经常用到这个概念:

假如我们有一个父类Coffee 还有一个它的子类Suger那么我们将 Coffee coffee=new suger()就叫做父类引用指向子类对象;

总结一下它的特点吧:

1.子类suger对于父类的函数重写当使用父类coffee的时候会使用重写过后的函数

2.子类对于父类的重载函数使用父类引用的时候不能用,也就是只能用到父类引用里面定义有的函数

3.子类对于父类里面的变量假如重新赋值的话使用父类引用指向子类对象的话,coffee里面的变量也会变

还有就是再顺带总结一下父类以及子类的强制类型转换:(对于接口的操作与继承的关系是一样的)

          *父类强制转换成子类在编译的时候不会报错但是运行的时候回抛出异常不能进行类型转换
         * 在内存层面就是父类的内存空间小不能转化成内存空间更大的子类
         * 但是子类可以转化成内存小的父类,转化是指的 大的部分也就是自己加上的方法不能用,但是还可以再
         * 从父类转化成子类,此时就可以使用子类的方法了

下面就以代码的形式做一下总结:

//先定义一个接口
package test1;

public interface Coffee {
   public  int price=12;
   public void func1();
   public void func2();
}
//================定义父类
package test1;

public class Suger implements Coffee {

    private int price2=2;
    private int o=33;
    private int weight2=4;
	@Override
	public void func1() {
		System.out.println("func1");
	}

	@Override
	public void func2() {
		System.out.println("price是"+price2+"         weight是"+weight2);

	}
	public void func3() {
		System.out.println("func3");

	}
	public static void main(String[] args) {
		Coffee coff=new Suger();//接口亦可以定义成父类引用的形式   在装饰者模式里面用到很多
		Suger sug=new Suger();
		Coffee coff2=(Coffee)sug;
		coff2.func1();
		Suger sug2=(Suger)coff2;
		sug2.func2();
		System.out.println("========上面是对于强制类型转换的操作");
		//接口的操作与继承的操作在这里都一样
		sug.func2();
		
		sug.func3();
		coff.func1();
		
		//coff.func3();
	}

    }
//========================定义子类=============================================
package test1;

public class Test extends Suger {
	
	 private int price2=5;
	
	 private int weight2=6;
	

	@Override
	public void func1() {
		super.func1();
	}

	@Override
	public void func2() {
		System.out.println("price是"+price2+"   weight是"+weight2);
	}
	
    //重载
	public void func3(int i) {
		System.out.println(i);
	}
	public void func4() {
		System.out.println("func4");
	}

	public static void main(String[] args) {
		//==========子类强制转换成父类对象还可以强制转换回子类对象
		Test test=new Test();
		Suger suger=(Suger)test;
		//suger.func4();// 强转过后子类独有的方法不能用了
		Test test2=(Test)suger;
		test2.func4(); 
		System.out.println("========================================");
		/*
		 * 父类强制转换成子类在编译的时候不会报错但是运行的时候回抛出异常不能进行类型转换
		 * 在内存层面就是父类的内存空间小不能转化成内存空间更大的子类
		 * 但是子类可以转化成内存小的父类,转化是指的 大的部分也就是自己加上的方法不能用,但是还可以再
		 * 从父类转化成子类,此时就可以使用子类的方法了
		 *  Exception in thread "main" func4
			java.lang.ClassCastException: test1.Suger cannot be cast to test1.Test
		    at test1.Test.main(Test.java:39)
		 */
		//Suger suger11=new Suger();
		//Test test3=(Test)suger11;
		//Suger suger12=(Suger)test3;
		//test3.func4();
		//suger11.func4();错误
		Suger sug=new Test();
		Test tes=new Test();
		sug.func1();
		sug.func2();//方法二进行过重载
		sug.func3();
		//sug.func3(666);错误因为在父类里面没有定义
		//sug.func4();
		System.out.println("============================tes===========================================");
		tes.func1();
		tes.func2();
		tes.func3(100000);
		tes.func4();
		
		//System.out.println(o);//private不可见
	}

}

输出结果:

        父类Suger:

func1
price是2         weight是4
========上面是对于强制类型转换的操作
price是2         weight是4
func3
func1

      子类Test:

func4
========================================
func1
price是5   weight是6
func3
============================tes===========================================
func1
price是5   weight是6
100000
func4

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值