• 抽象类与接口


    目录

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

    抽象类

    • 先从继承开始
      继承是为了代码的复用。
      现在有 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
  • 相关阅读:
    KVM虚拟机高级设置——09 设置KVM虚拟机开机自动启动
    KVM虚拟机高级设置——08 管理远程虚拟机
    搭建KVM环境——07 带GUI的Linux上安装KVM图形界面管理工具
    搭建KVM环境——06 创建虚拟机
    TightVNC安装
    数据库设计
    Free lunch is over
    【问题】使用XShell连接Debian,没有语法高亮
    【Intel 汇编】ELF文件
    【问题】No manual entry for pthread_create in section 3
  • 原文地址:https://www.cnblogs.com/s3abiscuit/p/7263760.html
Copyright © 2020-2023  润新知