ym——抽象与接口包含(工厂+适配器+代理)模式讲解

抽象类和接口抽象类

abstract class A{      // 是定义了一个抽象类

publicstatic final String FLAG = "CHINA" ;  //全局常量

privateString name = "Cym" ;    // 定义一个普通的属性

publicvoid setName(String name){

this.name = name ;

}

publicString getName(){

return this.name ;

}

publicabstract void print() ;           // 定义抽象方法

};

包含一个抽象方法的类称为抽象类,抽象方法是只声明而未实现的方法,所有的抽象方法必须使用abstract关键字声明,所有的抽象类也需要abstract关键字声明。

abstract class A{      // 是定义了一个抽象类

publicstatic final String FLAG = "CHINA" ;  //全局常量

privateString name = "Cym" ;       // 定义一个普通的属性

publicvoid setName(String name){

this.name = name ;

}

publicString getName(){

return this.name ;

}

publicabstract void print() ;           // 定义抽象方法

};

class B extends A{  // 继承抽象类,因为B是普通类,所以必须覆写全部抽象方法

publicvoid print(){

System.out.println("FLAG = " +FLAG) ;

System.out.println("姓名 = " + super.getName()) ;

}

};

对于抽象类来将,不能直接实例化的操作,但是可以声明,如果要使用抽象类,则必须依靠子类,抽象类是必须被子类继承,而且被继承的子类需要实现抽象中的全部抽象方法。

问题:

抽象类是否可以使用final关键字修饰呢?

抽象类必须被子类继承。

被final修饰的类不能被继承。

所以得出结论,抽象类不能使用final关键子修饰。

抽象类是否可以存在构造方法?

abstract classA{      // 是定义了一个抽象类

public A(){

System.out.println("A、抽象类中的构造方法。") ;

}

};

class B extendsA{  // 继承抽象类,因为B是普通类,所以必须覆写全部抽象方法

public B(){

super();

System.out.println("B、子类中的构造方法。") ;

}

};

public classAbstractDemo03{

public static void main(String args[]){

Bb = new B() ;

}

};

抽象类中允许有构造方法,但是此构造方法不能直接调用的,是交给子类调用的,子类对象的实例化过程中,永远是先调用父类中的构造方法。

抽象类就是比普通类多了一个抽象方法而已。

抽象类属性如何初始化?

abstract class Person{

privateString name ;              // 定义name属性

privateint age ;                     // 定义age属性

publicPerson(String name,int age){

this.name = name ;

this.age = age ;

}

publicvoid setName(String name){

this.name = name ;

}

publicvoid setAge(int age){

this.age = age ;

}

publicString getName(){

return this.name ;

}

publicint getAge(){

return this.age ;

}

publicabstract String getInfo() ;      // 抽象方法

};

使用super

class Student extends Person{

privateString school ;

publicStudent(String name,int age,String school){

super(name,age) ;     // 指定要调用抽象类中有两个参数的构造方法

this.school = school ;

}

publicvoid setSchool(String school){

this.school = school ;

}

publicString getSchool(){

return this.school ;

}

publicString getInfo(){

return      "姓名:" + super.getName()  +

";年龄:" + super.getAge() +

";学校:" + this.getSchool() ;

}

};

public class AbstractDemo04{

publicstatic void main(String args[]){

Student stu = new Student("张三",30,"清华大学") ;

System.out.println(stu.getInfo()) ;

}

};

抽象类中的属性如果要想初始化,则肯定还要依赖与构造方法。

接口

接口是一个特殊的类,在java中接口是由抽象方法和全局常量组成。

在java中使用interface定义一个接口

interface A{            // 定义接口A

publicstatic final String AUTHOR = "CYM" ;      //全局常量

publicabstract void print() ;    // 抽象方法

publicabstract String getInfo() ;      // 抽象方法

}

在此接口中定义两个抽象方法,一个全局常量,那么接口与抽象类一样,需要有子类,那么子类此时不再称为继承类,而是实现类,通过implements关键字实现完成。

接口的方法和属性永远是pubic修饰符

默认是方法是abstract

属性是 static final

既然接口从定义上已经明确了要求是由抽象方法和全局常量组成,那么在接口定义的时候就可以简化操作

interface A{            // 定义接口A

StringAUTHOR = "Cym" ;   // 全局常量

voidprint() ;    // 抽象方法

StringgetInfo() ;      // 抽象方法

}

一个类是虽然值能继承一个父类,但是一个类可以同时实现多个接口。

如果一个类既要实现接口又要继承抽象类的话,则必须按照一下的形式完成。

Class 子类extends 抽象类 implements 接口A,接口B,......{}

interface A{            // 定义接口A

publicString AUTHOR = "CYM" ;       //全局常量

publicvoid print() ; // 抽象方法

publicString getInfo() ;   // 抽象方法

}

abstract class B{      // 定义抽象类B

publicabstract void say() ;      // 定义抽象方法

}

class X extends B implements A{   // X类线继承B类,再实现A接口

publicvoid say(){

System.out.println("HelloWorld!!!") ;

}

publicString getInfo(){

return "HELLO" ;

}

publicvoid print(){

System.out.println("作者:" + AUTHOR) ;

}

};

public class InterfaceDemo04{

publicstatic void main(String args[]){

X x = new X() ;      // 实例化子类对象

x.say() ;

x.print() ;

}

};

接口里面的方法可以简写方法不写abstract关键字,但是抽象类里一定要修abstract关键字。

interface A{            // 定义接口A

publicString AUTHOR = "CYM" ;       //全局常量

publicvoid print() ; // 抽象方法

publicString getInfo() ;   // 抽象方法

}

abstract class B implements A{       // 定义抽象类B,实现接口A

publicabstract void say() ;      // 定义抽象方法

}

class X extends B{  // X类线继承B类

publicvoid say(){

System.out.println("HelloWorld!!!") ;

}

publicString getInfo(){

return "HELLO" ;

}

publicvoid print(){

System.out.println("作者:" + AUTHOR) ;

}

};

public class InterfaceDemo05{

publicstatic void main(String args[]){

X x = new X() ;      // 实例化子类对象

x.say() ;

x.print() ;

}

};

一个抽象类可以实现多个接口,但是一个接口不能继承一个抽象类。

interface A{            // 定义接口A

publicString AUTHOR = "CYM" ;       //全局常量

publicvoid printA() ;      // 抽象方法

}

interface B{

publicvoid printB() ;

}

interface C extends A,B{

publicvoid printC() ;

}

class X implements C{    // X类线继承B类

publicvoid printA(){

System.out.println("A、Hello World!!!") ;

}

publicvoid printB(){

System.out.println("B、Hello MLDN") ;

}

publicvoid printC(){

System.out.println("C、Hello LXH") ;

}

};

public class InterfaceDemo06{

publicstatic void main(String args[]){

X x = new X() ;      // 实例化子类对象

x.printA() ;

x.printB() ;

x.printC() ;

}

};

一个接口虽然不可以继承一个抽象类,但是一个接口却可以同时继承多个接口。

对象多态性

接口和抽象类的基本概念完成了,下面最重要的就是对象的多态性,是整个java中最重要的一个部分,因为有多态性的存在,才可以让程序变的更加灵活。

多态性是面向对象的最后一个特征:

方法的重载和方法的覆写实际上就属于多态行的一种体现。

真正的多态性中还包含了一种为对象多态性概念。

对象多态性主要指的是,子类和父类对象的相互转换关系。

向上转型:父类 父类对象 = 子类实例  --》自动完成

向下转型:子类 子类对象 = (子类)父类实例 --》强制完成

classA{

publicvoid fun1(){

System.out.println("1、A类 --> public void fun1(){}") ;

}

publicvoid fun2(){

this.fun1() ;

}

};

class B extends A{

publicvoid fun1(){  // 将方法覆写了

System.out.println("2、B类 --> public void fun1(){}") ;

}

publicvoid fun3(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("3、B类 --> public void fun3(){}") ;

}

};

public class PolDemo01{

publicstatic void main(String args[]){

A a = new B() ;       // 发生向上转型关系,子类实例 --> 父类实例

a.fun2() ;

}

};

父类对象 = 子类实例(向上转型)

只能使用父类有的方法。(子类如果覆写则使用子类覆写的方法)

class A{

publicvoid fun1(){

System.out.println("1、A类 --> public void fun1(){}") ;

}

publicvoid fun2(){

this.fun1() ;

}

};

class B extends A{

publicvoid fun1(){  // 将方法覆写了

System.out.println("2、B类 --> public void fun1(){}") ;

}

publicvoid fun3(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("3、B类 --> public void fun3(){}") ;

}

};

public class PolDemo02{

publicstatic void main(String args[]){

A a = new B() ;       // 发生向上转型关系,子类实例 --> 父类实例

B b = (B)a ;    // 发生向下转型关系,强制

b.fun3() ;

b.fun2() ;

}

};

父类对象 = 子类实例

子类对象 = (子类)父类对象(向下转型)

class A{

publicvoid fun1(){

System.out.println("1、A类 --> public void fun1(){}") ;

}

publicvoid fun2(){

this.fun1() ;

}

};

class B extends A{

publicvoid fun1(){  // 将方法覆写了

System.out.println("2、B类 --> public void fun1(){}") ;

}

publicvoid fun3(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("3、B类 --> public void fun3(){}") ;

}

};

public class PolDemo03{

publicstatic void main(String args[]){

A a = new A() ;

B b = (B)a ;

b.fun2() ;

}

};

会产生ClassCastException,表示转换异常,造成的根本原因是两个没有关系的类进行相互的对象操作。

观察对象多态性的作用:

假如:现在要设计一个方法,那么此方法可以接受A类的所有子类的实例。

如果现在不使用对象多态性的概念完成

class A{

public void fun1(){

System.out.println("1、A类 -->public void fun1(){}") ;

}

public void fun2(){

this.fun1() ;

}

};

class B extends A{

public void fun1(){  // 将方法覆写了

System.out.println("2、B类 -->public void fun1(){}") ;

}

public void fun3(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("3、B类 -->public void fun3(){}") ;

}

};

class C extends A{

public void fun1(){  // 将方法覆写了

System.out.println("4、C类 -->public void fun1(){}") ;

}

public void fun4(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("5、C类 -->public void fun4(){}") ;

}

};

public class PolDemo04{

public static voidmain(String args[]){

fun(new B()) ;

fun(new C()) ;

}

public static void fun(Bb){

b.fun2() ;

b.fun3() ;

}

public static void fun(Cc){

c.fun2() ;

c.fun4() ;

}

};

以上的方式是通过重载完成,那么使用以上方法完成会存在以上的缺点,如果现在A类的子类有N个,那么方法就要重载N次,而且每次增加子类的时候都需要修改代码本身。

所以,此时使用对象多态性就可以很好的解决此类问题,因为所有的对象都会发生自动的向上转型操作。

class A{

public void fun1(){

System.out.println("1、A类 -->public void fun1(){}") ;

}

public void fun2(){

this.fun1() ;

}

};

class B extends A{

public void fun1(){  // 将方法覆写了

System.out.println("2、B类 -->public void fun1(){}") ;

}

public void fun3(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("3、B类 -->public void fun3(){}") ;

}

};

class C extends A{

public void fun1(){  // 将方法覆写了

System.out.println("4、C类 -->public void fun1(){}") ;

}

public void fun4(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("5、C类 -->public void fun4(){}") ;

}

};

public class PolDemo05{

public static voidmain(String args[]){

fun(new B()) ;

fun(new C()) ;

}

public static void fun(Aa){

a.fun2() ;

}

};

class A{

public void fun1(){

System.out.println("1、A类 -->public void fun1(){}") ;

}

public void fun2(){

this.fun1() ;

}

};

class B extends A{

public void fun1(){  // 将方法覆写了

System.out.println("2、B类 -->public void fun1(){}") ;

}

public void fun3(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("3、B类 -->public void fun3(){}") ;

}

};

class C extends A{

public void fun1(){  // 将方法覆写了

System.out.println("4、C类 -->public void fun1(){}") ;

}

public void fun4(){  // 此操作为子类自己定义的,父类中不存在

System.out.println("5、C类 -->public void fun4(){}") ;

}

};

public class PolDemo08{

public static voidmain(String args[]){

fun(new B()) ;

fun(new C()) ;

}

public static void fun(Aa){

a.fun2() ;

if(a instanceof B){

B b = (B)a ;

b.fun3() ;

}

if(a instanceof C){

C c = (C)a ;

c.fun4() ;

}

}

};

如果要使用子类自身的方法为了保证对象向下转型操作正确,在操作前最好加上instanceof关键字判断。

在继承关系中,父类的设计很重要,只要父类的设计合理了,则代码开发非常简便。

抽象类的应用

从对象多态性的概念来看,子类为父类实例化是一个比较容易的操作,以为可以发生自动的向上转型关系,那么调用的方法永远是被子类覆写过的方法。

那么,此时就可以利用此概念通过对象多态性为抽象类实例化。

抽象类可以实现方法,当很多类有相同方法和并且相同实现的时候,我们就可以用抽象类。当然也可以覆写。

抽象类本身最大的用处就是在于模版设计。

接口的应用

接口也可以像抽象类那样通过多态性进行对象的实例化操作。

抽象类可以用于定义模版操作,但是接口呢?

接口实际上是作为一个标准存在的。

接口不可以的实现方法,但很多类只要有相同方法操作的时候,我们就可以用接口作为一种标准。

接口和抽象类适配器设计模式

正常情况下一个接口的子类要实现全部的抽象方法

interface Window{

publicvoid open() ; // 打开窗口

publicvoid close() ; // 关闭窗口

publicvoid icon() ;  // 最小化

publicvoid unicon() ;      // 最大化

}

Class MyWindow implements Window{

在MyWindow类此时肯定要覆写全部的抽象方法,但是现在希望可以根据自己的需要来选择覆写,那么该怎么实现?

用一个类先将接口实现了,但是所有的方法都属于空实现,之后再继承此类。

应该使用抽象类,因为抽象类也不能直接使用。

interfaceWindow{

public void open() ; // 打开窗口

public void close() ; // 关闭窗口

public void icon() ;  // 最小化

public void unicon() ;      // 最大化

}

abstract classWindowAdapter implements Window{

public void open(){}

public void close(){}

public void icon(){}

public void unicon(){}

};

class MyWindowextends WindowAdapter{

public voidopen(){

System.out.println("打开窗口!");

}

};

public classAdpaterDemo{

public static void main(String args[]){

Windowwin = new MyWindow() ;

win.open();

}

}

工厂设计模式

interface Fruit{

publicvoid eat() ;

}

class Apple implements Fruit{

publicvoid eat(){

System.out.println("吃苹果。。。") ;

}

};

class Orange implements Fruit{

publicvoid eat(){

System.out.println("吃橘子。。。") ;

}

};

Public class interDemo{

Public staticvoid main(String args[]){

Fruit f = new Apple();

F.eat();

}

以上的程序如果开发的话是存在问题?

一直强调:主方法实际上就是一个客户端。客户端的代码越简单越好。

interface Fruit{

publicvoid eat() ;

}

class Apple implements Fruit{

publicvoid eat(){

System.out.println("吃苹果。。。") ;

}

};

class Orange implements Fruit{

publicvoid eat(){

System.out.println("吃橘子。。。") ;

}

};

class Factory{  // 工厂类

publicstatic Fruit getFruit(String className){

Fruit f = null ;

if("apple".equals(className)){

f= new Apple() ;

}

if("orange".equals(className)){

f= new Orange() ;

}

return f ;

}

};

public class InterDemo{

publicstatic void main(String args[]){

Fruit f = Factory.getFruit(args[0]) ;

if(f!=null){

f.eat();

}

}

}

所有接口的实例化对象都是工厂类取得的。那么客户端调用的时候根据传入的名称不同,完成不同的功能。

代理设计模式

interface Give{

publicvoid giveMoney() ;

}

class RealGive implements Give{

publicvoid giveMoney(){

System.out.println("把钱还给我。。。。。") ;

}

};

class ProxyGive implements Give{  // 代理公司

privateGive give = null ;

publicProxyGive(Give give){

this.give = give ;

}

publicvoid before(){

System.out.println("准备:小刀、绳索、钢筋、钢据、手枪、毒品") ;

}

publicvoid giveMoney(){

this.before() ;

this.give.giveMoney() ;   // 代表真正的讨债者完成讨债的操作

this.after() ;

}

publicvoid after(){

System.out.println("销毁所有罪证") ;

}

};

public class ProxyDemo{

publicstatic void main(String args[]){

Give give = new ProxyGive(new RealGive());

give.giveMoney() ;

}

};

当两个类同时实现一个接口,一个类需要另外一个类代理才能实现该功能,这就叫代理模式。

抽象类与接口的区别

NO

比较点

抽象类

接口

1

组成

抽象方法、普通方法、常量、变量、构造、方法、全局变量

抽象方法、全局常量

2

定义

Abstract

interface

3

子类

子类通过extends继承抽象类

子类通过implements实现接口

4

限制

一个子类只能继承一个抽象类

一个子类能够同时实现多个接口

5

关系

一个抽象类可以实现多个接口

一个抽象类中可以包含多个接口

一个接口不能继承一个抽象类

一个接口可以包含多个抽象类

6

设计模式

模版设计

工厂模式、代理模式

7

实例化

都是通过对象的多态性、通过子类进行对象实例化操作

8

实现限制

存在单继承局限

不存在单继承局限

9

特性

一个标准、一种能力

         

如果抽象类和接口同时都可以使用的话、优先接口,以为接口可以避免单继承的局限。

抽象类包含接口

abstract class A{

publicabstract void fun() ;

interfaceB{     // 内部接口

public void print() ;

}

};

class X extends A{

publicvoid fun(){

System.out.println("****************");

}

classY implements B{

public void print(){

System.out.println("===================");

}

};

};

public class TestDemo01{

publicstatic void main(String args[]){

A a = new X() ;

a.fun() ;

A.B b = new X().new Y() ;

b.print() ;

}

};

接口包含抽象类

interface A{

publicvoid fun() ;

abstractclass B{      // 内部抽象类

public abstract void print() ;

}

};

class X implements A{

publicvoid fun(){

System.out.println("****************");

}

classY extends B{

public void print(){

System.out.println("===================");

}

};

};

public class TestDemo02{

publicstatic void main(String args[]){

A a = new X() ;

a.fun() ;

A.B b = new X().new Y() ;

b.print() ;

}

};

ym——抽象与接口包含(工厂+适配器+代理)模式讲解

时间: 2024-10-12 21:28:29

ym——抽象与接口包含(工厂+适配器+代理)模式讲解的相关文章

五、 接口延伸出的代理模式

示例: // 主题接口:定义了核心功能 interface Subject { public abstract void eat(); } // 核心主题:实现了主题接口,并且只实现核心功能 class RealSubject implements Subject { public void eat() { System.out.println("核心主题RealSubject要XXXX"); } } // 代理主题:实现了主题接口,完成核心主题的辅助性工作 class ProxySu

JAVA学习--接口的应用:代理模式

1 public class TestProxy { 2 public static void main(String[] args) { 3 Object obj = new ProxyObject(); 4 obj.action(); 5 } 6 } 7 8 interface Object{ 9 void action(); 10 } 11 //代理类 12 class ProxyObject implements Object{ 13 Object obj; 14 15 public P

设计模式学习笔记(十九:代理模式)

1.1概述 为其他对象提供一种代理以控制对这个对象的访问.这就是代理模式的定义. 当用户希望和某个对象打交道,但程序可能不希望用户直接访问该对象,而是提供一个特殊的对象,这个特殊的对象被称作当前用户要访问对象的代理,程序让用户和对象的代理打交道,即让用户通过访问代理来访问想要访问的对象.在代理模式中,代理的特点是:它与所代理的对象实现了相同的接口,也就是说代理和它多代理的对象向用户公开了相同的方法,当用户请求代理调用该方法时,代理可能需要验证某些信息或检查它所代理的对象是否可用,当代理确认它所代

java/android 设计模式学习笔记(9)---代理模式

这篇博客我们来介绍一下代理模式(Proxy Pattern),代理模式也成为委托模式,是一个非常重要的设计模式,不少设计模式也都会有代理模式的影子.代理在我们日常生活中也很常见,比如上网时连接的代理服务器地址,更比如我们平时租房子,将找房子的过程代理给中介等等,都是代理模式在日常生活中的使用例子. 代理模式中的代理对象能够连接任何事物:一个网络连接,一个占用很多内存的大对象,一个文件,或者是一些复制起来代价很高甚至根本不可能复制的一些资源.总之,代理是一个由客户端调用去访问幕后真正服务的包装对象

二十三种设计模式[12] - 代理模式(Proxy Pattern)

前言 代理模式,属于对象结构型模式.在<设计模式 - 可复用的面向对象软件>一书中将之描述为" 为其它对象提供一种代理以控制对这个对象的访问 ". 在代理模式中,通常使用一个类来代表另一个类的功能,并由这个代理对象去控制原对象的引用. 结构 Subjuet(公共接口):代理类和被代理类的公共接口,保证任何使用目标的地方都可以被代理类替换: RealSubject(被代理类):代理类所代表的目标类: Proxy(代理类):包含对目标类的引用,目标类的封装: 场景 在日常生活中

24天学会设计模式------代理模式

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.代理模式 1.模式定义 代理模式(Proxy Pattern):给某一个对象提供一个代理,并由代理对象控制对原对象的引用.代理模式的英文叫做Proxy或Surrogate.代理模式是一种对象结构型模式. 2.模式动机 一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,去掉客户不能看到的内容和服务或者增添客户需要的额外服务.如在网页上查看一张图片,

设计模式 代理模式之静态代理

静态代理要搞清楚三个关系:客户类   代理类   委托类  代理类的行为要类似且强于委托类(实现方法有1.继承,2.代理类与委托类实现共同的接口(首选)) /** * 用静态代理模式完成日志的操作 * @author Administrator * */public class UserAction { private UserDao userDao = UserDaoFac.newUserDao(); public void add(){ System.out.println("=======

JavaSE-接口之静态代理模式

package com.btp.t2; /* * 接口的应用:代理模式 */ public class TestProxy { public static void main(String[] args) { Object obj=new ProxyObject(); obj.action(); } } interface Object{ void action(); } //代理类 class ProxyObject implements Object{ Object obj; @Overri

第14章 结构型模式—代理模式

1. 代理模式(Proxy Pattern)的定义 (1)为其他对象提供一种代理以控制对这个对象的访问 ①代理模式在客户和被客户访问的对象之间,引入了一定程度的间接性,客户是直接使用代理,让代理来与被访问的对象进行交互. ②这种附加的间接性增加了灵活性和不同的用途. (2)代理模式的结构和说明 ①Proxy:代理对象,通常实现与具体的目标对象一样的接口,这样就可以使用代理来代替具体的目标对象. A.保存一个指向具体目标对象的指针,可以在需要的时候调用具体的目标对象,若RealSubject和Su