《JAVA编程思想》学习备忘(第277页Polymorphism-3)

续《JAVA编程思想》学习备忘(第277页Polymorphism-2)

Behavior of polymorphic methods inside constructors

示例:

class Glyph {
 void draw(){
  System.out.println("Glyph.draw()");
 }
 Glyph(){
  System.out.println("Glyph() before draw()");
  draw();
  System.out.println("Glyph() after draw()");
 }
}

class RoundGlyph extends Glyph{
 private int radius = 1;
 RoundGlyph(int r){
  radius = r;
  System.out.println("RoundGlyph.RoundGlyph(),radius = " + radius);
 }
 void draw(){
  System.out.println("RoundGlyph.draw(),radius = " + radius);
 }
}

public class PolyConstructors {
 public static void main(String[] args) {
  new RoundGlyph(5);
 }
}
输出:

Glyph() before draw()
RoundGlyph.draw(),radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(),radius = 5
为什么在父类构造函数还没有完成时,子类的重写方法确已经执行了呢?

来看上例初始化的实际进程:

1、在任何事物发生之前,内存为对象开辟空间被初始化为二进制大小0;

2、父类构造函数首先被调用,在此点,调用了重写的draw()方法,根据进程1得知:radius被付值为0;

3、按声明顺序调用成员初始化者;

4、子类的构造函数体被调用。

 

Covariant return types

Java SE5 adds covariant return types,which means that an overridden method in a derived class can return a type derived from the type returned by the base-class method:

class Grain {
 public String toString(){return "Grain";}
}

class Wheat extends Grain{
 public String toString(){return "Wheat";}
}

class Mill{
 Grain process(){return new Grain();}
}

class WheatMill extends Mill{
 Wheat process(){return new Wheat();}
}

public class CovariantReturn {
 public static void main(String[] args) {
  Mill m = new Mill();
  Grain g = m.process();
  System.out.println(g);
  m = new WheatMill();
  g = m.process();
  System.out.println(g);
 }
}

输出:

Grain
Wheat

 

Designing with inheritance

...A better approach is to choose composition first,especially when it's not obvious which one you should use.Composition does not force a design into an inheritance hierarchy.But composition is also more flexble since it's possible to dynamically choose a type(and thus behavior)when using composition,whereas inheritance requires that an exact type be known at compile time.The following example illustrates this:

class Actor {
 public void act(){}
}

class HappyActor extends Actor{
 public void act(){
  System.out.println("HappyActor");
 }
}

class SadActor extends Actor{
 public void act(){
  System.out.println("SadActor");
 }
}

class Stage{
 private Actor actor = new HappyActor();
 public void change(){actor = new SadActor();}  //重构
 public void performPlay(){actor.act();}
}

public class Transmogrify {
 public static void main(String[] args) {
  Stage stage = new Stage();
  stage.performPlay();
  stage.change();
  stage.performPlay();
 }
}

输出:

HappyActor
SadActor

A general guideline is "Use inheritance to express differences in behavior,and fields to express variations in state."

 

Substitution vs. extension

...the base class can receive any message you can send to the derived class because the two have exactly the same interface.

 

Downcasting and runtime type information

(类型)向下强转与运行时类型信息

示例:

class Useful {
 public void f(){}
 public void g(){}
}

class MoreUseful extends Useful{
 public void f(){}
 public void g(){}
 public void u(){}
 public void v(){}
 public void w(){}
}

public class RTTI {
 public static void main(String[] args) {
  Useful[] x = {
    new Useful(),
    new MoreUseful()
  };
  x[0].f();
  x[1].g();

  //x[1].u();  //通不过编译

  ((MoreUseful)x[1]).u();//向下强转
  ((MoreUseful)x[0]).u();//能通过编译,但运行时抛出ClassCastException异常
 }
}

 

Summary

Polymorphism means"different forms."In OOP,you have the same interface from the base class,and different forms using that interface:the different versions of the dynamically bound methods.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值