1. 抽象类只是在普通类的基础上扩充了一些抽象的方法,所谓的抽象方法指的是只声明而为实现的方法(即没有方法体)。所有的抽象方法要求使用abstract关键字来定义,并且抽象方法所在的类也一定要使用abstract关键字来定义,表示抽象类。
  2. 抽象类中包含抽象方法,而抽象方法不包含方法体,因此抽象类不能直接产生实例化对象。
abstract class Person {  //抽象类
	private String name;
	public String getName() {   //普通方法
		return this.name;
	}
	public void setName() {    getter和setter方法获取私有属性
		this.name = name;
	}
	//抽象方法
	public abstract void getPersonInfo();
}
  1. 对于抽象类的使用原则:

● 所有的抽象类必须有子类
● 抽象类的子类必须覆写抽象类的所有抽象方法(方法覆写注意权限问题,尽量都用public)
● 抽象类的对象可以通过对象多态性利用子类为其实例化(向上转型)
● private和abstract不能同时使用
● 抽象类不可以直接被实例化
● 如果抽象类继承了抽象类,那么作为子类的抽象类可以不实现父类抽象类的抽象方法
● 抽象类里面可以包含非抽象方法

//抽象类
abstract class Person {
	private String name;
	public String getName() {  //非抽象方法
		return this.name;
	}
	public void setName() {
		this.name = name;
	}
	//抽象方法
	public abstract void getPersonInfo();
}
//子类继承抽象类
class Student extends Person {
	//覆写父类抽象类的抽象方法
	public void getPersonInfo() {
		System.out.println("I am a student");
	}
}
public class Test {
	public static void main(String[] args) {
		//实例化子类,向上转型
		Person per = new Student();   	
		//调用被子类覆写的方法
		per.getPersonInfo();
	}
}
  1. 抽象类的使用规则:

● 实例化子类时一定先调用父类构造方法
● 如果父类没有无参构造,那么子类构造必须使用super()明确指出使用父类哪个构造方法
● 如果没有构造方法,那么对象中的属性一定都是其对应数据类型的默认值,即没有构造方法,无法初始化属性。

1.第一个例子
//在抽象类中定义构造方法
abstract class Person {
	private String name;
	//构造方法
	public Person() {
		System.out.println("*******");
	}
	public String getName() {  //非抽象方法
		return this.name;
	}
	public void setName() {
		this.name = name;
	}
	//抽象方法
	public abstract void getPersonInfo();
}

2.第二个例子
//父类没有无参构造,子类必须使用super()明确指出使用父类的哪个构造方法
abstract class A {
	//3.调用父类构造
	public A() {
	//4。调用被子类覆写的方法
		this.print();
	}
	public abstract void print();
}
class B extends A {
	private int num = 10;
	//2.调用子类实例化对象
	public B(int num) {
		//3.隐含一行语句,首先要调用父类构造方法
		super();
		//7.为类中属性初始化
		this.num = num;
	}
	//5.此时子类对象的属性还没被初始化
	public void print() {
		//6.对应其数据类型的默认值
		System.out.println(this.num);
	}
}
public class Test {
	public static void main(String[] args) {
		//1.实例化子类对象,匿名对象
		new B(20);
	}
}
  1. 对象的实例化操作所需的核心步骤:

● 进行类加载(双亲委派模型)
● 进行类对象的空间开辟(为类对象开辟空间)
● 进行类对象中的属性初始化(构造方法)
● 抽象类中允许不定义任何的抽象方法,但是此时抽象类依然无法直接创建实例化对象,即不能A a = new A(); ● 抽象类一定不能使用final声明,因为被final声明的类不允许有子类,抽象类必须有子类;抽象方法不能使用private定义,因为抽象方法必须要能被覆写。
● 外部抽象类中不允许使用static,内部抽象类允许使用

//内部类允许使用static
abstract class A {
	public abstract void printA();
	static abstract class B {
		public abstract void printB();
	}
}
//继承抽象类A中的内部抽象类B
class X extends A.B {
	//重写B类的抽象方法
	public void printB() {}
}
  1. 开闭原则(OCP):一个软件实体如类、模块和方法应该对扩展开发、对修改关闭。(java最基础的设计原则)
  2. 模板设计模式:完成一件事有固定个数的步骤,但是每个步骤根据对象的不同,而实现的细节不同,因此就可以在父类中定义一个完成该事情的总方法,按照完成事情需要的步骤去调用其每个步骤的实现方法,而每个步骤的具体实现,由子类完成。
  3. 钩子方法(hook):是一类“默认不做事的方法“,在父类中通常是默认实现,子类可以视情况决定要不要覆盖它们。
//钩子方法
boolean customerWantsCondiments() {
	reutrn true;
}
  1. 接口:是抽象方法和全局变量的集合,在java中接口用interface关键字定义。建议在所有接口前面追加字母I。
//定义一个接口
interface IMessage {
	public static final String MSG = "I am a biter"; //全局变量
	public abstract void print();  //抽象方法
}
  1. 接口的相关规则:

1)子类如果要想使用接口,就必须使用implements关键字来实现接口,同时,一个子类可以用,来实现多个接口,接口的子类必须覆写接口中的全部抽象方法。
2)接口不能实例化,可以利用子类的向上转型通过实例化子类来得到接口的实例化对象。
3)接口中的数据成员默认为 public static final。
4)接口中的方法默认为 public abstract。
5)接口中不能有已经实现的方法。
6)如果一个抽象类继承了接口,那么该抽象类中可以不实现接口的抽象方法,但是如果再有一个普通类继承了此抽象类,那么普通类一定要实现接口和抽象类的所有抽象方法。

//实例
interface IMessage {
	//全局变量
	public static final String MSG = "I am a biter";
	//抽象方法
	public abstract void print();
}
interface INews {
	//抽象方法
	public abstract String getNews();
}
//一个普通类继承了多个接口
class MessageImpl implements IMessage,INews {
	//覆写接口IMessage的抽象方法
	public void print() {
		System.out.println(IMessage.MSG); 
	}
	//覆写接口INews的抽象方法
	public String getNews() {
		//访问常量都建议加上类名称
		return IMessage.MSG;
	}
}
public class Test {
	public static void main(String[] args) {
		//利用子类向上转型,实例化子类来实现父类接口实例化对象
		IMessage m = new MessageImpl();
		//调用被子类覆写过的方法
		m.print();
		INews n = (INews) m;
		System.out.println(n.getNews());
	}
}
  1. 接口的使用限制;

1)接口中只允许public权限(属性和方法都是);
2)接口的两种定义方式

完整格式

简化格式

interface IMessage

interface IMessage {

{ public final String MSG = “I am a biter";

String MSG = “I am a biter”;

public abstract void print(); }

void print(); }

3)当一个子类即需要实现接口又需要继承抽象类时,请先使用extends继承一个抽象类,而后使用imples实现多个接口。

//子类继承抽象类和实现接口
interface IMessage {
	public void print();
}
abstract class News {
	public abstract void getNews();
}
//子类先继承抽象类再实现接口
class MessageImpl extends News implements IMessage {
	//覆写接口中的抽象方法
	public void print() {
		System.out.println("I am a biter");
	}
	//覆写父类中的抽象方法
	public void getNews() {
		System.out.println("I am News");
	}
}

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

interface IMessage {
	public void print();
}
//抽象类实现接口
abstract class News implements IMessage {
	//News为抽象类,可以不实现IMessage中的抽象方法
	public abstract void getNews();
}

5)一个接口可以使用extends继承多个父接口。

interface A {
	public void printA();
}
interface B {
	public void printB();
}
//接口多继承
interface C extends A,B {
	public void printC();
}

6)接口可以定义一系列的内部结构,包括:内部类、内部接口。其中,使用static定义的内部接口就相当于一个外部接口。因为static修饰的时全局的,存储在共享区。

interface A {
	public void printA();
	//使用static定义,描述一个外部接口
	static interface B {
		public void printB();
	}
}
calss Impl implements A.B {
	public void printB() {}
}
  1. 接口的应用:

1)定义操作标准
2)表示能力
3)在分布式开发中暴露远程服务方法

  1. 简单工厂模式:专门定义一个类用来创建其他类的实例,被创建的实例通常都具有共同的父类(只有一个接口即抽象产品类)。通俗来说就是具有一个抽象产品类,具体产品类和一个工厂。

打个比方,假设你需要去买电脑,电脑就是一个抽象产品类,而电脑的品牌有很多,如苹果、小米、戴尔、微软等等,但是这些电脑都是在一个工厂中生产出来的,例如富士康公司就是这类工厂,它负责生产各种品牌电脑的生产,当你需要买一台电脑时,这是就定义了一个抽象产品类即电脑,而当你选择一个具体的电脑品牌如苹果电脑时,工厂就接受到信息,开始生产苹果电脑,然后产生具体产品类,然后你得到的就是你所需要的苹果电脑。在此过程中,抽象产品类就是一个接口,工厂和具体产品类去实现这个接口,并且类的实例化即电脑的具体品牌在工厂中实现。这种设计方法的缺点就是当需要添加具体产品时需要修改工厂,违反了OCP开放封闭原则。

  1. 工厂方法模式:定义一个用来创建对象的接口,让子类决定实例化哪一个类,让子类决定实例化延迟到子类(有两个接口即抽象产品类和抽象工厂)。具体而言,工厂方法模式是简单工厂模式的扩展,具有一个抽象产品类、多个具体产品类、一个抽象工厂、多个具体工厂(每一个具体产品对应于一个具体工厂)。

工厂方法模式就是当你需要买一台电脑时,即产生了抽象产品类,由于电脑的品牌太多,所以你需要决定你所需要的电脑品牌,而这些电脑品牌就是所谓的多个具体工厂所生产的具体产品类,一个工厂对应生产一个具体产品,而每个工厂都是在一个总的抽象工厂的分厂。也就说你买电脑这个过程首先是你定义了一个电脑的抽象产品类的接口,然后通过具体工厂去实现抽象工厂这个接口,进而产生具体产品类,具体产品类再去实现电脑这个抽象类的接口,就得到了你所需要的电脑品牌。这种设计模式增加了代码量,每个具体的产品都需要一个具体的工厂去实现,而增加抽象产品时,会违背OCP原则。

  1. 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它具有多个抽象产品类、具体产品类、抽象工厂类、具体工厂类。

抽象工厂模式是在工厂方法模式的前提上进行的扩展,工厂方法模式只是生产一个产品,而抽象工厂模式是生产两个或以上的产品。还是拿买电脑来举例子,你去买电脑,不但需要购买电脑主体还需要生产相对应的操作系统,这里将生产电脑和生产操作系统分开,抽象工厂提供返回抽象产品的方法,也就是抽象工厂提供了生产电脑和生产操作系统的方法,然后生产电脑即创建电脑这个抽象产品由生产电脑的具体工厂类去实现,而生产操作系统即创建操作系统这个接口由生产相应操作系统的具体工厂区实现,最终得到电脑与操作系统一致的产品。这种设计模式再扩展产品族的时候会违反OCP原则。

  1. 代理设计模式:两个子类共同实现一个接口,其中一个子类负责真实业务实现,另外一个子类完成辅助真实业务主体的操作。

代理模式的本质:所有的真实业务操作都会有一个与之辅助的工具类(功能类)共同完成。
代理模式就是在购买电脑时,真实的业务只是购买一台电脑,但是在购买电脑这个真实的业务后面包含了生产电脑、以及售后保障等多个业务,而这些业务就是与真实的业务所配套的辅助业务。

  1. 抽象类和接口的区别:

区别

抽象类(abstract)

接口(interface)

结构组成

普通类+抽象方法

抽象方法+全局变量

权限

各种权限

public

子类使用

使用extends关键字继承抽象类

使用implements关键字实现接口

关系

一个抽象类可以实现若干个接口

接口不能继承抽象类,但是接口可以使用extends关键字继承多个父接口

子类限制

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

一个子类可以实现多个接口