抽象类与接口

目录

  • 抽象类
    • 先从继承开始
    • 继承无法解决的问题
    • 为什么抽象类不能实例化对象
  • 接口
    • 抽象方法的问题
    • 使用接口解决
  • 总结
    • 被继承的普通类---抽象类(对部分方法抽象)---接口(全部由抽象方法组成)

抽象类

  • 先从继承开始
    继承是为了代码的复用。
    现在有 MallardDuck (绿头鸭),RocketDuck (火箭鸭),RubberDuck (橡皮鸭)。
    三种鸭子都能在水上漂流 float,而且漂浮的方式都是一样的。这样可以定义一个父类。三种鸭子通过继承获得漂流的方法,好处是不用每个鸭子都要再写一遍 float 方法。
class Duck{
  public void float(){
    System.out.println("All ducks can float");
  }
}
class MallardDuck extends Duck{}
class RocketDuck extends Duck{}
class RubberDuck extends Duck{}
  • 继承无法解决的问题
    不同的是三种鸭子的飞行方式,这时候就不能简单的在Duck类中实现fly方法。(当然可以在每个子类中覆写fly方法,此时父类中的fly方法就没有必要具体实现)解决办法是把飞行这个动作抽象为fly方法。然后由每个子类具体实现fly方法。这时候 Duck 就成了抽象类。注意要使用 abstract 关键字声明类名。
  • 为什么抽象类不能实例化对象?
    因为抽象类没有完整的描述一个类(fly方法没有具体实现)。
abstract class Duck{
  public void float(){
    System.out.println("All ducks can float");
  }
  public abstract void fly();
}
class MallardDuck extends Duck{
  public void fly(){
    System.out.println("I am flying with wings"); 
  }
}

class RocketDuck extends Duck{
  public void fly(){
    System.out.println("I am flying with rockets");
  }
}

class RubberDuck extends Duck{
  public void fly(){
    System.out.println("I cannot fly"); 
  }
}

接口

  • 抽象方法无法解决的问题
    假设现在有个RedheadDuck, 它的飞行方式和MallardDuck相同。这时候又要重新写一遍 MallardDuck 的 fly 方法。如果有成千上万的类需要重写的话,那后果可想而知。

  • 使用接口解决

    • 定义接口存放fly方法
    • 为每个具体的fly方法实现接口
    • 子类实例化时传入具体飞行方法
interface FlyBehavior{
  fly();
}
class FlyWithWings implements FlyBehavior{
  public void fly(){
   System.out.println("I am flying with wings");   
  }
}
class FlyWithRockets implements FlyBehavior{
  public void fly(){
    System.out.println("I am flying with rockets");  
  }
}
class FlyNoWay implements FlyBehavior{
  public void fly(){
   System.out.println("I cannot fly");  
  }
}

现在重新写Duck类

class Duck { 

  FlyBehavior flyBehavior;
  
  public Duck(FlyBehavior fb){
    flyBehavior = fb;
  }

  public void performFly() {
    flyBehavior.fly(); 
  } 
 
  public void float() {
    System.out.println("All ducks can float");
  }

}
class MallardDuck extends Duck{
	public MallardDuck(){
		super(new FlyWithWings());
	}
}
class RocketDuck extends Duck{
	public RocketDuck(){
		super(new FlyWithRockets());
	}
}
class RubberDuck extends Duck{
	public RubberDuck(){
		super(new FlyNoWay());
	}
}
class RedheadDuck extends Duck{
	public RedheadDuck(){
		super(new FlyWithWings());
	}
}

现在开始测试

public class DuckTest { 
  public static void main(String[] args) { 
    Duck mallard = new MallardDuck(); 
    Duck rocket = new RocketDuck(); 
    Duck rubber = new RubberDuck(); 
    Duck redhead = new RedheadDuck(); 
    mallard.performFly(); 
    rocket.performFly();
    rubber.performFly();
    redhead.performFly();
  } 
}
I am flying with wings
I am flying with rockets
I cannot fly
I am flying with wings

这样只需要在定义具体类的时候传入飞行的方式就行了。即使有再多的类也可以因为所有的飞行方式都已经实现了。

References

Three passions, simple but overwhelmingly strong, have governed my life: the longing for love, the search for knowledge, and unbearable pity for the suffering of mankind
原文地址:https://www.cnblogs.com/s3abiscuit/p/7263760.html