Java13--接口以及用法+设计模式
- 1 接口
- 1.1 概念
- 1.2 特点
- 1.3 入门案例
- 2 接口的用法
- 2.1 构造方法
- 2.2 成员变量
- 2.3 接口的成员方法
- 3 接口的复杂用法
- 4 总结
- 5 设计模式
- 5.1 单例设计模式概念
- 5.2 源码剖析
- 5.3 饿汉式
- 5.4 懒汉式
- 6 拓展
- 6.1 abstract注意事项
- 6.2 接口和抽象类的区别
- 6.3 设计学员示例
- 6.4 了解软件设计的开闭原则OCP
1 接口
1.1 概念
Java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现。
Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为java结构层次上的顶层。
interface 接口名{ 代码… }
1.2 特点
1、 接口中都是抽象方法
2、 通过interface关键字创建接口
3、 通过implements让子类来实现
4、 可以理解成,接口是一个特殊的抽象类
5、 接口突破了java的单继承的局限性
6、 接口和类之间可以多实现,接口和接口之间可以多继承
7、 接口是对外暴露的规则,是一套开发规范
8、 接口提高了程序的功能扩展,降低了耦合性
1.3 入门案例
package day10;
public class T {
public static void main(String[] args) {
Zi z = new Zi();
z.study();
z.teach();
}
}
interface Fu{
public abstract void study();
public abstract void teach();
}
//实现+重写
class Zi implements Fu{
public void study(){
System.out.println("Zi..study()");
}
public void teach(){
System.out.println("Zi..teach()");
}
}
2 接口的用法
2.1 构造方法
接口里是没有构造方法的。
在创建实现类的对象时默认的super(),是调用的默认Object的无参构造。
interface Fu{//定义一个接口
public abstract void show();
//Interfaces cannot have constructors
/*public Fu(){
System.out.println("Fu.Fu()");
}*/
}
2.2 成员变量
接口里没有成员变量,都是常量。所以,你定义一个变量没有写修饰符时,默认会加上:
public static final
package day10;
//构造函数,成员方法,成员变量
public interface Test7_Fu {
}
interface Fu2{//定义一个接口
//int num=10;//1,成员变量
//static int num=10;//2,默认就是静态的
//final static int num=10;//3,默认就是final的
public final static int num=10;//4,默认就是public的
class Zi7 implements Fu2{
}
class Test7Demoo{
public static void main(String[] args) {
Zi7 z= new Zi7();
//The final field Fu2.num cannot be assigned
//z.num=30;//默认是final的,不能修改值
System.out.println(z.num);
System.out.println(Fu2.num);
}
}
2.3 接口的成员方法
接口里的方法,默认就都是抽象的,如果你不写明是abstract的,那会自动补齐。
例如:public abstract void save
package cn.tedu.interfacedemo;
//这个类用来测试接口的使用
public class Test2_UseInter {
public static void main(String[] args) {
//测试
// Inter2 in = new Inter2();//3、接口不能创建对象
Inter2 in = new Inter2Impl();
// in.count = 20 ;//4、是最终的,The final field Inter2.count cannot be assigned
System.out.println( in.COUNT );
System.out.println( Inter2.COUNT );//5、是静态的
in.get();
in.update();
}
}
//创建接口
interface Inter2{
//1、接口里可以有构造方法吗? --- 不能!!
// public Inter2() {}
//2、接口里可以有成员变量吗? --- 没有!!
//public static final int count = 10;//简写,接口会为变量自动拼接 public static final
int COUNT = 10 ;
//3、接口里可以有成员方法吗? --- 可以,但都是抽象方法!!
//public abstract void update() ; // 简写,接口会为方法自动拼接 public abstract
void update() ; // 简写,接口会为方法自动拼接 public abstract
void get() ;
}
class Inter2Impl implements Inter2{
@Override
public void update() {
System.out.println("update()...");
}
@Override
public void get() {
System.out.println("get()...");
}
}
3 接口的复杂用法
Java中单继承的局限性通过接口可以解决。
接口可以多继承也可以多实现,甚至可以继承的同时多实现。
package cn.tedu.interfacedemo;
//这个类用来测试接口的复杂用法:多继承多实现
public class Test4_ComInter {
public static void main(String[] args) {
Interface1 in = new Interface1Impl();
in.save();
in.update();
}
}
//创建接口1
interface Interface1{
void save();
void update();
}
//创建接口2
interface Interface2{
void get();
void delete();
}
//1、打破了java单继承的局限性,因为接口之间可以多继承,多个接口之间逗号隔开
interface Interface3 extends Interface1,Interface2{
void add();
}
//3、接口还可以多实现吗??---可以多实现,只不过接口之间逗号隔开
class ManyImpl implements Interface1,Interface2{
public void save() {}
public void update() {}
public void get() {}
public void delete() {}
}
//4、接口可以继承的同时,多实现?? --
class MoreImple extends ManyImpl implements Interface1,Interface2 {
}
//2、创建实现类,使用3号接口的功能,需要重写几个方法呢??---同时重写1号和2号和3号接口里的所有功能
class Interface3Impl implements Interface3{
@Override
public void save() { }
@Override
public void update() { }
@Override
public void get() { }
@Override
public void delete() { }
@Override
public void add() { }
}
//TODO 创建实现类
class Interface1Impl implements Interface1{
@Override
public void save() {
System.out.println("save()...");
}
@Override
public void update() {
System.out.println("update()...");
}
}
4 总结
1、类和类的关系:继承 extends / 单继承 / 单根继承
-- 继承的意义:为了提高代码的复用性,减少了代码的编写提高开发效率。
-- 方法重写的意义:在不修改父类源码的前提下,在子类中重写业务,从此使用的就是重写后的功能。
-- 要求子类的方法声明和父类一样,只要改方法体。
-- 有了继承有了重写就产生了多态,多态的意义:为了统一程序的调用标准,标准就是父类。
-- 多态 也就是向上转型/向上造型。
-- 向下造型的意义:很少用,相当于想要使用子类的特殊功能,还不如直接创建子类对象简单。
-- class A extends B
-- 其中,A和B都是类,A是子类,B是父类,A就拥有了B的所有功能(除了私有的和构造方法)
-- 其他知识点:this 和super ,构造方法,各种代码块...
2、类和接口关系:实现implements / 单实现 / 多实现
-- class A implements B,C
-- 其中,A是实现类,B和C是接口
-- 要求A 可以把 B 和C 接口里的所有 抽象方法 都重写掉,否则 A 就是抽象类
-- 接口不能创建对象
-- 接口里没有构造方法,接口里都是常量,接口里都是抽象方法
3、接口和接口关系:继承extends / 单继承 / 多继承
-- 接口的多继承的关系,打破了java单继承的局限性
-- interface A extends B,C
-- 其中,A B C 都是接口,A是子接口,同时拥有B和C接口里的所有功能
-- class AImpl implements A
-- 要求AImpl需要重写A接口里的所有方法(是包含B和C接口的所有方法),否则就是抽象类
4、接口和抽象类的区别!!!
-- 相同点:都是抽象层,都不能实例化
-- 不同点:
-- 1、抽象类用abstract关键字描述,接口用interface
-- 2、子类和抽象类之间是extends关系,实现类和接口之间是implements关系
-- 3、抽象类中 可以 有构造方法 ,接口里 不能 出现 构造方法
-- 4、抽象类里可以有 变量,接口里没有变量全都是静态的常量
-- 5、接口里定义常量的语法:public static final String NAME="jack",会为变量自动拼接public static final
-- 6、抽象类里 可以有普通方法 也可以有 抽象方法,接口都是抽象方法
-- 7、抽象类和子类之间是继承关系,而且java中,只支持单继承
-- 8、接口突破了java单继承的局限性,因为接口可以多继承也可以多实现,甚至可以继承的同时多实现
-- 9、接口的复杂用法
-- 多继承: interface A extends B,C 其中A是子接口,同时拥有自己的和BC的功能
-- 多实现: class AImpl implements M,N,O,P 其中AImpl是实现类,需要同时重写MNOP的所有抽象方法,否则就是一个抽象类
-- 继承的同时多实现: class AImpl extends Object implements M,N 一定是先继承后实现
5 设计模式
Java中有23 种设计模式,本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性,以及类的关联关系和组合关系的充分理解。
当然,软件设计模式只是一个引导,在实际的软件开发中,必须根据具体的需求来选择。
1、 对于简单的程序,可能写一个简单的算法要比引入某种设计模式更加容易。
2、 但是对于大型项目开发或者框架设计,用设计模式来组织代码显然更好。
5.1 单例设计模式概念
单例模式可以说是大多数开发人员在实际中使用最多的,常见的Spring默认创建的bean就是单例模式的。
单例模式有很多好处,比如可节约系统内存空间,控制资源的使用。
其中单例模式最重要的是确保对象只有一个。
简单来说,保证一个类在内存中的对象就一个。
RunTime就是典型的单例设计,我们通过对RunTime类的分析,一窥究竟。
5.2 源码剖析
/**
* Every Java application has a single instance of class
* <code>Runtime</code> that allows the application to interface with
* the environment in which the application is running. The current
* runtime can be obtained from the <code>getRuntime</code> method.
* <p>
* An application cannot create its own instance of this class.
*
* @author unascribed
* @see java.lang.Runtime#getRuntime()
* @since JDK1.0
*/
RunTime.java
package java.lang;
public class Runtime {
//1、创建静态的全局唯一的对象
private static Runtime currentRuntime = new Runtime();
//2、私有构造方法,
/** Don't let anyone else instantiate this class */
private Runtime() {}
//3、通过自定义的静态方法获取实例
public static Runtime getRuntime() {
return currentRuntime;
}
}
5.3 饿汉式
目的:控制外界创建对象的个数只能创建1个对象
开发步骤:
1、 私有化构造方法
2、 在类的内部创建好对象
3、 对外界提供一个公共的get(),返回一个已经准备好的对象
package cn.tedu.single;
//测试单例设计模式
public class Test8_Single {
public static void main(String[] args) {
Single s = Single.get();
Single s1 = Single.get();
//get()多少次,内存中使用的都是同一个对象
System.out.println(s);//cn.tedu.single.Single@15db9742
System.out.println(s1);//cn.tedu.single.Single@15db9742
}
}
class Single{
// 1、私有化构造方法,不让外界直接new
private Single() {}
// 2、在类的内部,创建好对象
//static :静态只能调用静态
static private Single s = new Single();
// 3、对外界提供一个公共的get(),返回一个已经准备好的对象
//static是为了外界不通过对象访问而是通过类名直接方法
static public Single get(){
//注意:静态只能调用静态
return s;
}
}
5.4 懒汉式
class Single{
// 1、私有化构造方法,不让外界直接new
private Single() {}
// 2、在类的内部,创建好对象
//static :静态只能调用静态
static private Single s = null;
// 3、对外界提供一个公共的get(),返回一个已经准备好的对象
//static是为了外界不通过对象访问而是通过类名直接方法
synchronized static public Single get(){
//注意:静态只能调用静态
if(s==null){
s = new Single();//会有安全问题
}
return s;
}
}
6 拓展
6.1 abstract注意事项
抽象方法要求子类继承后必须重写。那么,abstract关键字不可以和哪些关键字一起使用呢?以下关键字,在抽象类中。用是可以用的,只是没有意义了。
1、 private:被私有化后,子类无法重写,与abstract相违背。
2、 static:静态的,优先于对象存在。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。
3、 final:被final修饰后,无法重写,与abstract相违背。
6.2 接口和抽象类的区别
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
7、抽象类里可以没有抽象方法,如果要扩展抽象类的新方法,子类将很容易的就能得到这些新方法。
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。
6.3 设计学员示例
具体事物:培优班学员,高手班学员
共性:姓名,学号,学习方法,休假方法
利用面向抽象 、 面向接口的编程思想,完成程序设计。
6.4 了解软件设计的开闭原则OCP
开放功能扩展,关闭源码修改。等
开闭原则的英文全称是Open Close Principle,缩写是OCP,它是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的、灵活的系统。
开闭原则的定义是:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改是封闭的。
开闭原则,是一种设计模式,随着面向对象程序设计的思想,应运而生。
开,指的是可以在源代码的基础上进行扩展,比如继承,接口,抽象类等。在JAVA中,之所以用继承,是在可以直接调用类库的前提下,对其功能进行扩展。不需要应用者去了解封装类的内部逻辑就可以做开发。
闭:指不允许对原有的代码进行修改。以免影响其他现有功能,造成功能瘫痪。