JAVA学习---------多态

乐器与乐符的关系

package polymorphisn.music;

public enum Note {
    MIDDLE_C, C_SHARP, B_FLAT;
}

/

package polymorphisn.music;
import static net.mindview.util.Print.*;

class Instrument{
    public void play(Note n){
        print("Instrument.play()");
    }
}
public class Wind exends Instrument{
    public void play(Note n){
        System.out.println("Wind.play()"+n);
    }
}

/

package polymorphisn.music;

public class Music {
    public static void tune(Instrument i){
        i.play(Note.MIDDLE_C);
    }
    public static void main(String[] args){
        Wind flute = new Wind();
        tune(flute);
    }
}

//Output:
Wind.play() MIDDLE_C

       Wind引用传递到tune()方法是合适的,因为Wind是从Instrument继承而来,Instrument的接口存在于Wind之中,是一个包含的关系。

多态的关键:让tune()方法实现多态;

(1)未用多态的方法来实现多个方法

package polymorphism.music;
import static net.mindview.util.print.*;
class Stringed extends Instrument{
    public void play(Note n){
    print("Stringed.play()"+n);
    }
}

class Brass extends Instrument{
    public void play(Note n){
        print("Brass.play()"+n);
    }
}

public class Music2{
    public static void tune(Wind i){
        i.play(Note.MIDDLE_C);
    }
    public static void tune(Stringed i){
        i.play(Note.MIDDLE_C);
    }
    public static void tune(Brass i){
        i.play(Note.MIDDLE_C);
    }
    public static void main(String[] args){
        Wind flute = new Wind;
        String violin = new Stringed();
        Brass frencHorn = new Brass();
        tune(flute);
        tune(violin);
        tune(frenchHorn);
    }
}
///output:
Wind.play() MIDDLE_C
Stringed.play() MIDDLE_C
Bress.play() MIDDLE_C

(2)方法调用绑定

       将一个方法调用同一个方法主题关联起来称作绑定1.前期绑定:在程序执行前绑定;2.后期绑定(动态绑定):运行时根据对象的类型进行绑定;JAVA中除了static和final之外,所有方法都是后期绑定的。因此可以断定所有的方法都是自动发生。

final 方法目的为防止别人覆盖该方法,且运行前绑定,关闭动态绑定,或许可以在某些情况下提高性能。

(3)向上转型继承

package polymorphism.shape;

public class Shape{
    public void draw(){}
    public void erase(){}
}

package polymorphism.shape;
import static net.mindview.util.Print.*;

public class Circle extends Shape{
    public void draw(){print("Circle.draw()");}
    public void erase(){print("Circle.erase()");}
}

package polymorphism.shape;
import static net.mindview.util.Print.*;

public class Square extends Shape {
    public void draw(){print("Square.draw()");}
    public void erase(){print("Square.erase()");}
}

package polymorphism.shape;
import static net.mindview.util.Print.*;

public class Triangle extends Shape{
    public void draw(){print("Triangle.draw()");}
    public void erase(){print("Triangle.erase()");}
}

package polymophism.shape;
import java.util.*;

public class RandomShapeGenerator{
    private Random rand = new Random(47);
    public Shape next(){
        switch(rand.nextInt(3)){
            default:
            case 0: return new Circle();
            case 1: return new Square();
            case 2: return new Triangle();
        }
    }
}


import polymorphism.shape.*;

public class Shapes {
    private static RandomShapeGenerator gen =
     new RandomShapeGenerator();
    public static void main(String[] args){
        Shape[] s = new Shape[9];
        for (int i=0;i<s.length;i++){
            s[i]=gen.next();
        }
        for (Shape shp :s)
            shp.draw();
    }
}


///output

Triangle.draw()
Triangle.draw()
Square.draw()
Triangle.draw()
Square.draw()
Triangle.draw()
Square.draw()
Triangle.draw()
Circle.draw()

(4)“覆盖”私有方法

       

package polymorphism;
import static net.mindview.util.Print.*;

public class PrivateOverride{
    private void f() {print("private f()");}
    public static void main(String[] args){
        PrivateOverride po = new Derived();
        po.f();
    }
}

class Derived extends PrivateOverride{
    public void f(){print("public f()");}
}

//output
private f()

private 方法被自动认为是final的,无法覆盖。如果某个方法是静态的方法,他的行为就不具有多态性。即都会输出基类的方法;

(5)引用计数

         

import static net.mindview.util.Print.*;

class Shared{
    private int refcount =0;
    private static long counter =0;
    private final long id =counter++;
    public Shared(){
        print("Creating"+this);
    }
    public void addRef(){refcount++;}
    protected void dispose(){
       if (--refcount ==0)
        print("Disposing"+this);
    }
    public String toString(){return "Shared"+id;}
}
class Composing{
    private Shared shared;
    private static long counter =0;
    private final long id = counter++;
    public Composing(Shared shared){
        print("Creating"+this);
        this.shared=shared;
        this.shared.addRef();
    }
    protected void dispose(){
        print("disposing"+this);
        shared.dispose();
    }
    public String toString(){return "Composing"+id;}
}

public class ReferenceCounting{
    public static void main(String[] args){
        Shared shared = new Shared();
        Composing[] composing = {new Composing(shared),
        new Composing(shared),new Composing(shared),
        new Composing(shared),new Composing(shared)};
      for (Composing c:composing)
          c.dispose();
    }
}
///output
Creating Shared 0
Creating Composing 0
Creating Composing 1
Creating Composing 2
Creating Composing 3
Creating Composing 4
disposing Composing 0
disposing Composing 1
disposing Composing 2
disposing Composing 3
disposing Composing 4
disposing Shared 0

(6)继承设计

       继承在编译时需要知道确切的类型。

import static net.mindview.util.Print.*;

class Actor {
    public void act(){}
}

class HappyActor extends Actor{
    public void act(){print(HappyActor);}
}

class SadActor extends Actor {
    public void act(){print("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();
    }
}
///output
HappyActor
SadActor

(7)纯继承与扩展

     在基类中已有的方法才可以在导出类中被覆盖。

优点:基类可以接收发送给导出类的任何消息,因为二者有着完全相同的接口;

缺点:导出类中接口的扩展部分不能被基类访问,向上转型,无法调用这些新方法。

解决方案:向下转型,运行态的类型识别。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值