1.抽象类的定义与使用 定义:抽象类只是比普通类多了一些抽象方法而已 抽象方法:只声明而未实现的方法(没有方法体),抽象方法必须使用abcstract关键字来定义。并且抽象方法所在的类也一定要使用abstract来定义 public abstract void
1.1 抽象类的是使用原则 a.所有抽象类必须有子类(final与abstract不能同时出现) b.抽象类的子类必须覆写抽象类的所有抽象方法 c.抽象类无法直接创建实例化对象,需要通过子类向上转型为实例化 abstract class Person{ private String name; public String getName(){ return name; } public abstract void test(); } class student extends Person{ public void test(){ System.out.println("子类覆写抽象方法"); } } public class Test{ public static void main(String[] args){ Person per = new student(); per.fun(); } }
1.2 抽象类相关约定 1.2.1 抽象类一定存在构造方法,子类也一定遵循对象实例化流程。先调用父类构造再调用子类构造
1.2.2 抽象类可以没有任何抽象方法,但此时仍然不能直接创建实例化对象 1.2.3 final与abstract不能同时出现 private与abstract也不能同时出现 1.2.4 关于内部抽象类:子类只需要覆写外部抽象类的直接抽象方法即可。内部抽象类的方法可不覆写。
2.模板设计模式 开闭原则(OCP):一个软件实体如类、模块或函数应该对扩展开放,对修改关闭。
模板(模板方法)设计模式:基于抽象类 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板模式可以使得子类在不改变算法的前提下,重新定义算法中的某些步骤。
abstract class CaffeineBeverage { final void prepareRecipe() { boilWater(); 子类实现: brew(); pourInCup(); // 如果顾客想要饮料我们才调用加料方法 if (customerWantsCondiments()){ addCondiments(); } } abstract void brew(); abstract void addCondiments(); void boilWater() { System.out.println("Boiling water"); } void pourInCup() { System.out.println("Pouring into cup"); } boolean customerWantsCondiments() { return true; } }
class Tea extends CaffeineBeverage { void brew() { System.out.println("Steeping the tea"); } void addCondiments() { System.out.println("Adding Lemon"); } }
class Coffee extends CaffeineBeverage { void brew() { System.out.println("Dripping Coffee through filter"); } void addCondiments() { System.out.println("Adding Sugar and Milk"); } public boolean customerWantsCondiments() { String answer = getUserInput(); if (answer.equals("y")) { return true; }else { return false; } } private String getUserInput() { String answer = null; System.out.println("您想要在咖啡中加入牛奶或糖吗 (y/n)?"); Scanner scanner = new Scanner(System.in); answer = scanner.nextLine(); return answer; } }
public class Test { public static void main(String[] args) { CaffeineBeverage tea = new Tea(); CaffeineBeverage coffee = new Coffee(); System.out.println("\nMaking tea..."); tea.prepareRecipe(); System.out.println("\nMaking Coffee"); coffee.prepareRecipe(); } }
钩子方法(可以被覆写的方法)
3.接口的定义以及使用 接口优先原则:在一个操作既可以使用抽象类又可以使用接口的时候,优先考虑使用接口。
3.1 接口定义(JDK8以前) 接口就是抽象方法与全局常量的集合(纯粹版的抽象类),interface关键字定义接口 interfa IMyInterface{ //全局变量 public static final String MSG = "test"; //抽象方法 public abstract void test(); }
接口命名:接口使用I开头
子类要想使用接口,implements实现接口,一个子类可以同时实现多个接口(避免单继承局限)
子类命名规范:接口名为IMyInterFace,子类实现此接口命名为MyInterfaceImpl
父接口间的相互转换:前提是两个父接口拥有共同的实现子类
3.2 口使用限制 3.2.1 接口中只允许public权限(不管是常量还是方法,都是public权限,即便不写权限修饰符也是public)
阿里编码规约:接口中不要出现任何修饰符号,public也不要加
3.2.2 当子类既需要实现接口又需要继承抽象类时,请先使用extends继承一个抽象类,而后使用implements实现多个接口
3.2.3 一个抽象类可以使用implements实现多个接口,接口不能继承抽象类 class MessageImpl extends News implements IMessage
3.2.4 接口可以使用extends继承多个父接口(接口多继承)
3.3 接口应用 a.定义操作标准 b.表示能力 c.(了解)分布式开发中暴露远程服务方法
4.工厂设计模式 将客户端的new操作解耦到第三方(工厂类) 4.1 简单工厂-产品个数少且没有家族 a.一个抽象产品类(接口)- Computer b.多个具体产品类 - MacbookPro、SurfaceBook c.一个工厂(new 操作在此工厂中进行)- 客户端通过工厂类获取具体实例
4.2 工厂方法模式(横向扩展方便)-每个产品有自己家族,家族下有很多兄弟 定义一个用来创建对象的接口,让子类决定实例化哪一个类 针对每个产品(产品族)提供一个工厂类,客户端需要判断使用哪个工厂
a.一个抽象产品类 b.多个具体产品类 c.一个抽象工厂(-针对抽象产品类) d.多个具体工厂(每个产品家族拥有自己的工厂)
4.3 抽象工厂模式(了解)-多个产品线混合