第八章 多态 多态的优点与作用 和缺陷

1.可扩展性

  • 多态是一项让程序员“将改变的事物和未变的事物分离开来的重要技术”。
    改变的事物可能是添加了新的子类或父类和子类添加了新的方法,未变的事物可能是对基类的调用如 tune(Instrument i)方法调用,传入i的可能是个子类,而且可能会不断继承而产生新的子类
    但都不能影响这个方法,这个方法完全忽略周围的改变,这就是改变的事物和未变的事物分离开来。
  • 一个良好的OOP系统都遵循tune(Instrument i)的模型【Instrument是一个父类】,而且只与父类(Instrument)接口通讯。
    这样的程序时可扩展的,因为可以继承父类【Instrument】扩展出新的子类来,从而添加一些现有子类没有的功能、方法。
    class Instrument{
    	void play(Note n){System.out.println("Instrument.play()" + n);}
    	String what(){return "Instrument";}
    	void adjust(){System.out.println("Adjusting Instrument");}
    }
    class Wind extends Instrument{
    	void play(Note n){System.out.println("Wind.play()" + n);}
    	String what(){return "Wind";}
    	void adjust(){System.out.println("Adjusting Wind");}
    }
    class Percussion extends Instrument{
    	void play(Note n){System.out.println("Percussion.play()" + n);}
    	String what(){return "Percussion";}
    	void adjust(){System.out.println("Adjusting Percussion");}
    }
    ..........省略的代码
    public class Music {
    
    	//可以看到形式参数时以根父类,无论子类怎样扩展都不会影响这个tune方法
    	public static void tune(Instrument i){
    		i.play(Note.MIDDLE_C);
    	}
    	public static void tuneAll(Instrument[] e){
    		for(Instrument i : e)
    			tune(i);
    	}
    	public static void main(String[] args) {
    		Instrument[] orchestra = {
    				new Wind(),
    				new Percussion(),
    				new Stringed(),
    				new Brass(),
    				new Woodwind()
    		};
    		tuneAll(orchestra);
    	}
    }

2.缺陷1,覆盖 私有方法

  • public class PrivateOverride {
    	private void f(){System.out.println("private f()");}
    	public static void main(String[] args) {
    		//向上转型,会丢失子类中的方法
    		PrivateOverride po = new Derived();
    		po.f();
    	}
    }
    
    class Derived extends PrivateOverride{
    	public void f(){System.out.println("public f()");}
    }//输出private f()

    看上面的方法的输出我们期望的是输出Derived中的public f(),但是并没有,
    因为涉及向上转型,java会查找子类中重写的父类方法,如果有重写就执行子类重写的方法,没有,就执行父类的方法,
    在这个例子中,父类的f方法是私有的,不可能被重写,也就是说子类并没有重写,子类中的f只是他的新方法而已,有时向上转型,那就执行父类中的方法了。
  • 反过来可不可以,更不可以啦,反过来是子类没有重写f方法,因为他是private的。是子类私有的新方法。

3.缺陷2 域和静态方法

  • class Super{
    	public int field = 0;
    	public int getField(){return field;}
    }
    class Sub extends Super{
    	public int field = 1;
    	public int getField(){return field;}
    	public int getSuperField(){return super.field;}
    }
    
    public class FieldAccess {
    
    	public static void main(String[] args) {
    		Super sub = new Sub();
    		System.out.println(sub.field + sub.getField());
    		Sub sub2 = new Sub();
    		System.out.println(sub2.getSuperField());
    	}
    }

    看这段代码,任何域访问操作都是有编译器解析,也就是前期绑定,因此不是多态
    Super.field 和 Sub.field分配了不同的存储空间。
  • sub实际上包含了两个称为field的域,它自己的和从父类中得到的。
  • 引用中的field所产生的默认域并非Super版本的field域,要引用父类中的域,就是用super关键字吧。
  • 另外,如果某个方法是静态的,它的行为也不具有多态性


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值