天天看点

面向对象(高级)抽象类与接口的应用

本章目标:

掌握抽象类及接口的实例化操作

掌握模板设计的作用

掌握工厂设计模式应用

掌握代理设计模式应用

掌握适配器设计模式应用

掌握抽象类与接口的使用区别

为抽象类与接口实例化

在java中可以通过对象的多态性,为抽象类和接口实例化,这样再使用抽象类和接口的时候就可以本子类中所覆写过的方法了。

之所以抽象类和接口不能直接实例化,是因为其内部包含了各个抽象方法,抽象方法本身都是未实现的方法,所以无法调用。

通过对象多态性可以发现,子类发生了向上转型关系之后,所调用的全部方法都是被覆写过的方法。

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

可以继续使用此概念,为一个接口实例化

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

证明,如果要使用抽象类或接口,则只能按照以上操作完成。

抽象类的应用————定义模板

来看下面这样一种场景:“假设人分为学生和工人,学生和工厂都可以说话,但是学生和工人说话的内容不是一样的,也就是说话这个功能应该是一个具体功能,而说话的内容就要由学生或工人来决定”,所以此时就可以使用抽象类实现这种场景

图形表示:人可以说话、说话的内容由工人或学生决定

实例:

abstract class 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{
    private float score;
    public Student(String name,int age,float score){
        super(name,age);
        this.score = score;
    }
    public String getContent(){
        return    "学生信息 --> 姓名:"+super.getName()+
            "年龄:"+super.getAge()+
            "成绩:"+this.score;
    }
}
class Worker extends Person{
    private float salary;
    public Worker(String name,int age,float salary){
        super(name,age);
        this.salary = salary;
    }
    public String getContent(){
        return    "工人信息 ---> 姓名:"+super.getName()+
            "年龄:"+super.getAge()+
            "工资:"+this.salary;    
    }
}
public class AbstractCaseDemo02{
    public static void main(String args[]){
        Person per1 = null;//声明Person对象
        Person per2 = null;//声明person对象
        per1 = new Student("张三",20,99.0f);//学生是一个人
        per2 = new Worker("李四",30,3000.0f);//工人是一个人
        per1.say();
    }
}
           

显示生活中的模板:

违纪卡:

姓名:

班级:

日期:

事由:

3.3 接口的实际应用————制定标准

接口在实际中更多的作用是用来制定标准的。比如说:“U盘和打印机都可以插在电脑上使用,这是因为它们都实现了USB接口,对于电脑来说,只要符合了USB接口标准的设备就都可以插进来”

实例一:

interface USB{
    public void start();//USB设备开始工作
    public void stop();//USB设备结束工作
}
class Computer{
    public static void plugin(USB usb){
        usb.start();
        System.out.println("==========USB 设备工作==========");
        usb.stop();    
    }
}
class Flash implements USB{
    public void start(){
        System.out.println("U盘开始工作");
    }
    public void stop(){
        System.out.println("U盘停止工作");
    }

}
class Print implements USB{
    public void start(){
        System.out.println("打印机开始工作");
    }
    public void stop(){
        System.out.println("打印机停止工作");
    }
};
public class InterfaceCaseDemo02{
    public static void main(String args[]){
        Computer.plugin(new Flash());
        Computer.plugin(new print());
    }
}
           

如果深入学习的话,接口实际上还表示将方法的视图暴露给远程的客户端

3.4工厂设计模式

工厂设计模式,是在java开发中最常使用的一种设计模式

interface Fruit{//定义一个水果接口
    public abstract void eat();
}
class Apple implements Fruit{
    public void eat(){
        System.out.println("***吃苹果");    
    }
}
class Orange implements Fruit{
    public void eat(){
        System.out.println("***吃橘子");
    }
}
public InterfaceDemo03{
    public static void main(String args[]){
        Fruit f = new Apple();
        f.eat();
    }
}
           

分析:主方法:应该就表示一个客户端,主方法的代码越少越好。此时,直接在主方法中指定了要操作的子类,如果要更换子类,则肯定要修改客户端。就表示跟特定的子类紧密耦合在一起了。

JVM的工作原理:程序->JVM->操作系统

问题的解决:

通过过度端在程序中就称为工厂模式

interface Fruit{//定义一个水果接口
    public abstract 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 InterfaceDemo05{
    public static void main(String args[]){
        Fruit f = Factory.getInstance(args[0]);
        if(f!=null){
            f.eat();
        }
    }
}
           

3.5代理模式

假设现在有以下几种情况:

1.张三借李四 50000000这么多钱

2.李四不还了,张三生气了

3.张三找到王五,王五是要债公司

4.王五准备了枪支,绳索,刀子,刑法工具

5.王五把李四欠张三的钱要回来了

也就是说:张三委托王五跟李四要钱,也就是说王五代理了张三的请求

interface NetWork{
    public 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 = null;
        net = new Proxy(new Real());//指定代理操作
        net.browse();    //客户只关心上网浏览一个操作
    }
}
           

3.6适配器设计

此设计在今后的图形设计方面使用的很多。

例如:如果一个子类实现了一个接口,则肯定在子类中必须覆写此接口中的全部抽象方法,那么这样一来,如果一个接口中提供抽象方法过多,而且,没有必要全部实现的话,肯定很浪费。

实例一:

interface 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();
    }
}
           

3.7内部类的扩展

之前已经讲过内部类的概念。实际上在一个抽象类中还可以包含一个接口。

abstract class A{//定义抽象类
    public abstract void printA();    //抽象方法
    interface B{//定义内部接口
        public void printB();//定义抽象方法
    }
}
class X extends A{
    public void printA(){
        System.out.println("Hello--->A");
    }
    class Y implements B{
        public void printB(){
            System.out.println("Hello--->B");
        }
    }
}
public class InnerExtDemo01{
    public static void main(String args[]){
        A.B b = new X().new Y();
        b.printB();
    }
}
           

反之,在接口中也可以定义一个抽象类。

interface A{
    public void printA();    //抽象方法
    abstract class B{
        public abstract void printB();    //定义抽象接口
    }
};
class X implements A{
    public void printA(){
        System.out.println("hello--->A");
    }
    class Y extends B{
        public void printB(){
            System.out.println("hello--->B");
        }
    }
}
public class InnerExtDemo02{
    public static void main(String args[]){
        A.B b = new X().new Y();
        b.printB();
    }
}
           

但是,从实际的个人开发角度来讲,此种设计并不是很常见,因为代码的结构有些混乱了。

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

面向对象(高级)抽象类与接口的应用

重要的提示:

    在开发中,一个类永远不要去继承一个已经实现好的类,要么继承抽象类,要么实现接口,如果接口和抽象类同时都可以使用的话,那么优先使用接口,避免单继承局限。

4.总结:

1.抽象类和接口实例化:通过对象多态性。

2.抽象类表示一个模板,接口制定的是一个标准。

3.常见的设计模式:模板设计、工厂设计、代理设计、适配器设计。