Java抽象骨架实现


我们已经知道,Java提供了两种机制来定义允许多个实现的类型:接口和抽象类。但是这两种机制在某些情况下存在着一些我们不喜欢的地方。

比如,我们想模拟不同品牌的Android手机,需要实现一些手机的基本功能:开机、调节音量、下载App。

接口实现

我们先定义一个接口IAndroidPhone,提供相应的接口方法:

interface IAndroidPhone {
    void powerOn();     
    void setVolume(int volume);    
    void downloadApp(String appName);
}

现在,来定义一部三星手机:

class SamsungPhone implements IAndroidPhone {    

    @Override public void powerOn() {       
        System.out.println("长按电源键开机");   
    }
   
    @Override public void setVolume(int volume) {        
        if(volume < 0){            
            volume = 0;        
        }else if(volume > 100){            
            volume = 100;        
        }        
        System.out.println("把音量调节为:" + volume);    
    }
    
    @Override public void downloadApp(String appName) { 
        System.out.println("打开三星应用市场,搜索 " + appName + ",然后下载");    
    }
}

再定义一部Pixel手机

class PixelPhone implements IAndroidPhone {    
    @Override public void powerOn() {        
        System.out.println("长按电源键开机");    
    }
    
    @Override public void setVolume(int volume) {        
        if(volume < 0){            
            volume = 0;        
        }else if(volume > 100){            
            volume = 100;        
        }        
        System.out.println("把音量调节为:" + volume);    
    }
    
    @Override public void downloadApp(String appName) {   
        System.out.println("打开Google Play,搜索 " + appName + ",然后下载");    
    }
}

我们可以看到,一旦实现IAndroidPhone的接口,就需要实现它定义的所有方法。然而,其中某些方法是完全重复的。比如这里的powerOn()setVolume(int volume)方法,每实现一个不同品牌的手机就得把这些代码重复一次。


抽象类实现

我们把上面的IAndroidPhone接口定义成抽象类来试试,因为抽象类可以提供默认实现,所以我们定义一个抽象类AbstractAndroidPhone如下:

abstract class AbstractAndroidPhone {   
    void powerOn(){        
        System.out.println("长按电源键开机");    
    }
    
    void setVolume(int volume){        
         if(volume < 0){            
            volume = 0;        
        }else if(volume > 100){            
            volume = 100;        
        }        
        System.out.println("把音量调节为:" + volume);    
    }        
    
    abstract void downloadApp(String appName);
}

可以看到,抽象类AbstractAndroidPhone提供了powerOnsetVolume(int volume)方法的默认实现。

那么现在重新定义手机类SamsungPhone,让它继承AbstractAndroidPhone,并实现和之前同样的功能,代码如下:

class SamsungPhone extends AbstractAndroidPhone {    
    @Override    
    void downloadApp(String appName) {          
        System.out.println("打开三星应用市场,搜索 " + appName + ",然后下载");    
    }
}

这样子类只需要实现或者覆盖(override)它自己需要方法,因为抽象类提供的某些方法的默认实现已经满足了子类的实现需求。这样就不用重复写大量的相同代码。

但是使用抽象类也有很大的缺点,一旦一个类继承了抽象类AbstractAndroidPhone,那么它就无法继承其它类。而且我们也知道,继承实现有很多问题,太多的继承会造成代码耦合性问题,不利于以后的维护和升级。

抽象骨架实现类

抽象骨架实现类的出现就是为了避免以上两种实现方式的缺点。既不用写重复的代码,又能避免抽象类的限制。

我们定义一个抽象类AbsAndroidPhone来实现上面的IAndroidPhone接口,并给某些方法提供默认实现,如下:

abstract class AbsAndroidPhone implements IAndroidPhone{    
    @Override public void powerOn() {        
        System.out.println("长按电源键开机");    
    }    
    
    @Override public void setVolume(int volume) {       
        if(volume < 0){           
            volume = 0;       
        }else if(volume > 100){           
            volume = 100;       
        }        
        System.out.println("把音量调节为" + volume);    
    }    
}

现在重写之前的SamsungPhone类:

class SamsungPhone implements IAndroidPhone {     
    
    private SamsungPhoneImp samsungImp = new SamsungPhoneImp();    
    
    @Override  public void powerOn() {     
        samsungImp.powerOn();   
    }    
    
    @Override public void setVolume(int volume) {
        samsungImp.setVolume(volume);   
    }    
    
    @Override public void downloadApp(String appName) {
        samsungImp.downloadApp(appName);    
    }
    
    private static class SamsungPhoneImp extends AbsAndroidPhone{        
        @Override void downloadApp(String appName) {
            System.out.println("打开三星应用市场,搜索 " + appName + ",然后下载");       
        }  
    }   
    
}

在子类SamsungPhone中定义了一个私有类SamsungPhoneImp来实现抽象骨架实现类AbsAndroidPhone,并把接口方法的实现转发给该私有类的实例。

这样既避免了在子类中重复写大量相同的代码,又不会限制子类继承其它类,同时子类也可以根据需要实现其它接口。

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值