Java学习笔记之抽象类与接口的应用

1、抽象类的实际应用 — 定义模板

假设有这样的场景,将人分为工人和学生,两者都能说话,只是说话的内容不一样,换句话说,说话这个功能应该是一个具体功能,说话的内容由学生和工人决定,我们可以用抽象类实现这个场景

abstract class Person2{
    private String name;
    private int age;
    public Person2(String name, int age){
        this.name = name;
        this.age = age;

    }

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void say(){
        System.out.println(this.getContent());
    }

    public abstract String getContent();
}

class Student2 extends Person2{
    private String school;
    public Student2(String name,int age, String school){
        super(name, age);
        this.setSchool(school);
    }

    public void setSchool(String school){
        this.school = school;
    }

    public String getSchool() {
        return school;
    }

    public String getContent(){
        return "姓名:" + super.getName() + " 年龄:" + super.getAge() + " 学校:" + getSchool();
    }
}

class Worker2 extends Person2{
    private float salary;
    public Worker2(String name, int age, float salary){
        super(name, age);
        this.salary = salary;
    }

    public void setSalary(float salary) {
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    @Override
    public String getContent() {
        return "姓名:" + super.getName() + " 年龄:" + super.getAge() + " 收入:" + getSalary();
    }
}

public class AbstractClassAppDemo {
    public static void main(String[] args) {
        Student2 stu = new Student2("张三", 20, "NKU");
        Worker2 wk = new Worker2("李四",30,8000.0f);
        stu.say();
        wk.say();
    }
}

// 运行结果:
姓名:张三 年龄:20 学校:NKU
姓名:李四 年龄:30 收入:8000.0

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

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

interface USB{
    public void start();
    public void stop();
}

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 AbstractClassAppDemo {
    public static void main(String[] args) {
//        Student2 stu = new Student2("张三", 20, "NKU");
//        Worker2 wk = new Worker2("李四",30,8000.0f);
//        stu.say();
//        wk.say();
        Computer.plugin(new Flash());
        Computer.plugin(new Print());
    }
}

// 运行结果:
U盘开始工作
============ USB 设备工作 ===========
U盘结束工作
打印机开始工作
============ USB 设备工作 ===========
打印机结束工作

3、工厂设计模式

工厂设计模式是Java里最常见的一种设计模式,我们来看一下这段代码

interface Fruit{ 	// 定义一个水果接口
	public void eat();  // 吃水果
}

class Apple implements Fruit{
	public void eat(){
		System.out.println("** eat apple!")
	}
}

class Orange implements Fruit{
	public void eat(){
		System.out.println("** eat orange!")
	}
}

public class InterfaceDemo{
	public static void main(String args[]){
		Fruit f = new Apple();	// 实例化接口
		f.eat();
	}
}

思考:
上面的代码是否有问题?
可以看到,代码的逻辑没有问题,只是这样的设计是否合理呢?主方法我们理解为客户端,主方法里代码自然是越少越好,我们看到在主方法里直接指定了要操作的子类,如果要更换子类,就必须修改客户端,也就是说客户端和子类是耦合的。

在这里插入图片描述

interface Fruit{ 	// 定义一个水果接口
	public void eat();  // 吃水果
}

class Apple implements Fruit{
	public void eat(){
		System.out.println("** eat apple!")
	}
}

class Orange implements Fruit{
	public void eat(){
		System.out.println("** eat orange!")
	}
}
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 InterfaceDemo{
	public static void main(String args[]){
		Fruit f = Factory.getInstance(args[0]);	// 实例化接口
		if(f!=null){		// 判断是否获取实例
			f.eat();
		}
	}
}

在这里插入图片描述

4、代理设计模式

代理设计模式也是Java里用的比较多的一种设计模式,所谓的代理设计就是指用代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题则负责其它业务相关的处理。最常见的就是找代理上网,客户端通过网络代理连接网络,由代理服务器完成用户权限,访问限制等与上网相关的操作,

interface Network{
	public void browser();
}

class Real implements Network{
	public void browser(){
		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 browser(){
		this.check();
		this.network.browser();  // 调用真实的主题操作
	}
	
}

public class ProxyDemo{
	public static void main(String args[]){
		Network nw = new Proxy(new Real);	// 设置代理操作
		nw.browser();			// 客户只关心一个上网操作
	}
}

在这里插入图片描述

5、适配器设计

适配器设计在图形界面上用的非常多。
对于一个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 WindowImp extends WindowAdapter{
	public void open(){
		System.out.println("窗口打开")
	}
	public void close(){
		System.out.println("窗口关闭")
	}
	
}

public class WindowAdapterDemo{
	public static void main(String args[]){
		Window window = new WindowImp();
		window.open();
		window.close();
	}
}

6、总结

在这里插入图片描述

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

猜你喜欢

转载自blog.csdn.net/zuolixiangfisher/article/details/85238176