抽象类与接口的应用

目录

一 、为抽象类和接口实例化

二 、抽象类的实际应用----模板设计

三 、接口的实际应用----制定标准

四 、设计模式 ---- 工厂设计 

五 、设计模式 ---- 代理设计

六 、设计模式 ---- 适配器设计

七 、抽象类与接口之间的关系


 

一 、为抽象类和接口实例化

在Java中可以通过对象的多态性为抽象类和接口实例化,这样在使用抽象类和接口时即可调用子类中所覆写过的方法

 1 、通过子类为抽象类实例化

abstract class A{	// 定义抽象类A
    public abstract void print() ;	// 定义抽象方法print()
};
class B extends A {	// 定义子类,继承抽象类
    public void print(){		// 覆写抽象方法
        System.out.println("Hello World!!!") ;
    }
};
public class InstantiationDemo{
    public static void main(String args[]){
        A a = new B() ;		// 通过子类为抽象类实例化
        a.print() ;
    }
};

2 、通过子类为接口实例化

interface A{	// 定义接口A
    void print() ;	// 定义抽象方法print()
};
class B implements A {	// 定义子类,实现接口
    public void print(){		// 覆写抽象方法
        System.out.println("Hello World!!!") ;
    }
};
public class InstantiationDemo{
    public static void main(String args[]){
        A a = new B() ;		// 通过子类为接口实例化
        a.print() ;
    }
};

通过子类为抽象类和接口实例化,即可调用子类所覆写过的方法

 

 

二 、抽象类的实际应用----模板设计

有以下一种场景:现有学生和工人,两者都可以发言,发言的内容由学生和工人自己决定,从程序上来讲,学生和工人可以看作继承了“人类”的子类,此时就可以使用抽象类来实现这种场景

abstract class Person {   //定义抽象类Person
    private String name;
    private int age;
    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return this.name;
    }
    public int getAge() {
        return this.age;
    }
    public void say() {     //发言功能
        System.out.println(this.getContent());  //发言内容由子类决定
    }
    public abstract String getContent();  //定义抽象方法,由子类覆写,决定发言内容
}


class Student extends Person {  //定义Student类继承Person类
    private String school;
    public String getSchool(){
        return this.school;
    }
    public Student(String name,int age,String school) {
        super(name,age);
        this.school = school;
    }
    public String getContent() {   //覆写Person类方法,决定发言内容
        return "学生的发言内容 --> 姓名:" + super.getName() + ", 年龄:" + super.getAge() + ", 学校:" + this.getSchool();
    }
}

class Worker extends Person {  //定义Worker类继承Person类
    private float salary;
    public float getSalary(){
        return this.salary;
    }
    public Worker(String name,int age,float salary) {
        super(name,age);
        this.salary = salary;
    }
    public String getContent() {  //覆写Person类方法,决定发言内容
        return "工人的发言内容 --> 姓名:" + super.getName() + ", 年龄:" + super.getAge() + ", 薪水:" + this.getSalary();
    }
}

public class AbstractCaseDemo01 {
    public static void main(String[] args) {
        Person per1 = new Student("学生",20,"Java中学");  //由子类实例父类对象,即可调用子类所覆写过的方法
        Person per2 = new Worker("工人",30,5000.0f);  //由子类实例父类对象,即可调用子类所覆写过的方法
        per1.say();    //学生发言的内容
        per2.say();    //工人发言的内容
    }
}

程序运行结果:

以上程序中,Person类就相当于一个模板,每个子类实现模板中的抽象方法就能够产生不同的模板内容 

 

 

三 、接口的实际应用----制定标准

现实生活中,U盘和打印机等设备均可以通过USB接口在计算机上使用,因为他们都符合 USB接口 标准。以下实例通过接口模拟制定USB接口标准,实现此场景

interface USB {   //定义USB接口
    void start();
    void stop();
}

class Computer {   //计算机
    public static void plugin(USB usb) {  //只要是符合USB接口的设备都可以接入
        usb.start();               //让USB设备开始工作
        System.out.println("======USB设备工作中======");
        usb.stop();                //让USB设备停止工作
    }
}

class UDisk implements USB {    //U盘
    public void start() {   //覆写start()方法
        System.out.println("U盘已接入");
    }
    public void stop() {   //覆写stop()方法
        System.out.println("安全移除设备");
    }
}

class Print implements USB {  //打印机
    public void start() {  //覆写start()方法
        System.out.println("打印机已接入");
    }
    public void stop() {  //覆写stop()方法
        System.out.println("打印机停止工作");
    }
}

public class InterfaceCaseDemo01 {
    public static void main(String[] args) {
        Computer.plugin(new UDisk());  //接入U盘
        System.out.println(); //换行
        Computer.plugin(new Print());  //接入打印机
    }
}

程序运行结果:

从以上程序可以发现,接口就是一个标准,计算机认的只是接口,而对于具体的设备,计算机本身并不关心

 

 

四 、设计模式 ---- 工厂设计 

观察一下程序:

interface Fruit{
    void eat();
}

class Apple implements Fruit{
    public void eat(){
        System.out.println("==吃苹果==");
    }
}

class Orange implements Fruit{
    public void eat(){
        System.out.println("==吃橘子==");
    }
}

public class InterfaceCaseDemo02 {
    public static void main(String[] args) {
        Fruit f1 = new Apple();
        f1.eat();
        Fruit f2 = new Orange();
        f2.eat();
    }
}

程序运行结果:

在主方法中,子类为接口实例化后,调用被子类覆写过的方法,从程序中可以发现,每更换一个子类,都需要进行实例化,那么此时就可以在接口和子类之间加入一个过渡端,通过此过渡端进行实例化过程,返回接口实例

interface Fruit{
    void eat();
}

class Apple implements Fruit{
    public void eat(){
        System.out.println("==吃苹果==");
    }
}

class Orange implements Fruit{
    public void eat(){
        System.out.println("==吃橘子==");
    }
}

class Factory {  //定义工厂类
    public static Fruit getInstance(String className) {
        Fruit f = null;
        if("apple".equals(className)){  //判断是哪个子类
            f = new Apple();            //进行实例化
        }
        if("orange".equals(className)){
            f = new Orange();
        }
        return f;   //返回接口实例
    }
}

public class InterfaceCaseDemo03 {
    public static void main(String[] args) {
        Fruit f1 = null;
        f1 = Factory.getInstance("apple"); //通过工厂取得实例
        f1.eat();  //调用方法
    }
}

程序运行结果:

 

注意:进行字符串判断时把字符串常量写在前面可以避免空指向异常

public class EqualDemo {
    public static void main(String[] args) {
        String str = null;
        System.out.println(str.equals("hello"));  //空指向异常
    }
}

编译报错:

交换两个值的顺序,把字符串常量写在前面程序就不会报错

public class EqualDemo {
    public static void main(String[] args) {
        String str = null;
        System.out.println(("hello").equals(str));
    }
}

程序运行结果:

 

 

五 、设计模式 ---- 代理设计

代理设计是指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其它相关业务的处理,就好像生活中,用户通过网络代理服务器进行上网,由代理服务器完成用户权限和访问限制等相关的控制操作,而真实主题的服务器负责用户上网操作过程

interface Network{   //定义上网接口
    void browse();   //上网操作抽象方法
}

class Real implements Network{  //真实的上网操作
    public void browse(){
        System.out.println("上网冲浪~~");
    }
}

class Proxy implements Network{  //代理上网
    private Network network;
    public Proxy(Network network){
        this.network = network;
    }
    public void check(){   //上网相关的控制操作
        System.out.println("检查是否合法");
    }
    public void browse(){
        this.check();    //执行代理上网的相关控制操作
        this.network.browse();  //调用真实的上网操作
    }
}

public class ProxyDemo {
    public static void main(String[] args) {
        Network net = new Proxy(new Real());  //实例化代理,传入真实的上网操作
        net.browse();
    }
}

程序运行结果:

 

 

六 、设计模式 ---- 适配器设计

在Java程序中,如果一个类要实现一个接口,则必须要覆写此接口中的全部抽象方法,那么如果此时一个接口中定义的抽象方法过多,但是子类又用不到这么多的抽象方法,那么就比较麻烦。所以此时可以定义一个抽象类作为过渡,即一个接口首先被一个抽象类先实现(此抽象类通常称为适配器类),并在此抽象类中实现若干方法(方法体为空),则以后的子类直接继承此抽象类,就可以有选择地覆写所需要的方法

 

interface Window{		// 定义Window接口,表示窗口操作
    public void open() ;	// 打开
    public void close() ;	// 关闭
    public void activated() ;	// 窗口活动
    public void iconified() ;	// 窗口最小化
    public void deiconified();// 窗口恢复大小
}
abstract class WindowAdapter implements Window{
    public void open(){} ;	// 打开
    public void close(){} ;	// 关闭
    public void activated(){} ;	// 窗口活动
    public void iconified(){} ;	// 窗口最小化
    public void deiconified(){};// 窗口恢复大小
};
class WindowImpl extends WindowAdapter{
    public void open(){
        System.out.println("窗口打开。") ;
    }
    public void close(){
        System.out.println("窗口关闭。") ;
    }
};
public class AdapterDemo{
    public static void main(String args[]){
        Window win = new WindowImpl() ;
        win.open() ;
        win.close() ;
    }
};

程序运行结果:

通过适配器这个中间环节,子类就可以选择性地实现所需要的方法

提示:抽象类中可以不包含抽象方法

 

七 、抽象类与接口之间的关系

抽象类与接口在系统设计上用得最多,也是面向对象编程的核心,以下列出了两者的主要区别:

 

在类的设计中,需要记住一个原则:一个类不要去继承一个已经实现好的类,去继承抽象类或接口,如果接口和抽象类都可以使用,那么优先使用接口,避免单继承局限。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值