本章目标:
掌握抽象类及接口的实例化操作
掌握模板设计的作用
掌握工厂设计模式应用
掌握代理设计模式应用
掌握适配器设计模式应用
掌握抽象类与接口的使用区别
为抽象类与接口实例化
在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.常见的设计模式:模板设计、工厂设计、代理设计、适配器设计。