代码
接口:interface
接口和类是并列的两个结构
接口中定义全局常量
全局常量:public static final
的,可省略不写public static final
class Untitled {
public static void main(String[] args) {
System.out.println(A.MAX);
System.out.println(A.MIN);
//同样不可以修改,报错
//A.MIN = 1;
}
}
interface A{
//全局常量
public static final int MAX = 10;
//可省略不写 public static final
int MIN = 0;
}
接口中定义抽象方法
抽象方法:public abstract
的,可省略不写public abstract
interface A{
//全局常量
public static final int MAX = 10;
//可省略不写 public static final
int MIN = 0;
//抽象方法
public abstract void m();
//可省略不写 public abstract
void s();
}
实现类可以实现多个接口
格式:class AA extends BB implements CC,DD,EE{}
interface A{
int MIN = 0;
public abstract void m();
void s();
}
interface B{}
class C implements A,B{
public void m(){}
public void s(){}
}
接口与接口之间可以继承,而且是!!多继承!!此时实现类就必须重写所有的接口的抽象方法,否则就要声明成抽象类
interface A{
int MIN = 0;
public abstract void m1();
void m2();
}
interface B{
void m3();
}
interface C extends A,B{}
class D implements C{
public void m1(){}
public void m2(){}
public void m3(){}
}
接口的使用也满足多态性,实现类与接口之间可以用多态
class Untitled {
public static void main(String[] args) {
Computer c = new Computer();
Shubiao s = new Shubiao();
c.m(s); //实现了多态
}
}
class Computer{
public void m(USB b){ //USB b = new Shubiao();
b.start();
System.out.println("具体工作细节");
b.stop();
}
}
interface USB{
public abstract void start();
public abstract void stop();
}
class Shubiao implements USB{
public void start(){
System.out.println("鼠标开始工作");
}
public void stop(){
System.out.println("鼠标结束工作");
}
}
class Jianpan implements USB{
public void start(){
System.out.println("键盘开始工作");
}
public void stop(){
System.out.println("键盘结束工作");
}
}
接口中定义的静态方法只能通过接口来调用
class Untitled {
public static void main(String[] args) {
Sub s = new Sub();
//接口中定义的静态方法只能通过接口来调用
//s.m1();
CompareA.m1();
}
}
class Sub implements CompareA{
}
interface CompareA{
public static void m1(){
System.out.println("A的m1静态草莓");
}
public default void m2(){
System.out.println("A的m2西瓜");
}
default void m3(){
System.out.println("A的m3樱桃");
}
}
接口中定义的默认方法通过实现类的对象来调用
若实现类中重写了接口中的默认方法,则输出的是实现类重写的方法
class Untitled {
public static void main(String[] args) {
Sub s = new Sub();
//s.m1();
CompareA.m1();
s.m2();
s.m3();
}
}
class Sub implements CompareA{
public void m3(){
System.out.println("Sub的m3");
}
}
interface CompareA{
public static void m1(){
System.out.println("A的m1静态草莓");
}
public default void m2(){
System.out.println("A的m2西瓜");
}
default void m3(){
System.out.println("A的m3樱桃");
}
}
执行结果如下:
若父类和接口有同名方法,但是子类中没有重写,则子类调用时输出的是父类中的方法
class Untitled {
public static void main(String[] args) {
Sub s = new Sub();
//s.m1();
CompareA.m1();
s.m2();
s.m3();
}
}
class Super{
public void m3(){
System.out.println("Super的m3哈密瓜");
}
}
class Sub extends Super implements CompareA{
}
interface CompareA{
public static void m1(){
System.out.println("A的m1静态草莓");
}
public default void m2(){
System.out.println("A的m2西瓜");
}
default void m3(){
System.out.println("A的m3樱桃");
}
}
执行结果如下
若多个接口内有同名方法,但是实现类中没有重写,则会报错:接口冲突
这时候就必须在实现类中重写该方法
在子类(实现类)中调用接口、父类中的被子类重写的方法
class Untitled {
public static void main(String[] args) {
new Sub().methon();
}
}
class Super{
public void m3(){
System.out.println("Super的m3哈密瓜");
}
}
class Sub extends Super implements CompareA,CompareB{
public void m3(){
System.out.println("Sub的m3草莓");
}
public void methon(){
m3(); //调用自己重写的方法
super.m3(); //父类的方法
CompareA.super.m3(); //接口的方法
CompareB.super.m3(); //接口的方法
}
}
interface CompareA{
default void m3(){
System.out.println("A的m3西瓜");
}
}
interface CompareB{
default void m3(){
System.out.println("B的m3");
}
}
执行结果如下
接口匿名实现类对象
和抽象类的匿名子类对象一样的写法
class Untitled {
public static void main(String[] args) {
Computer com = new Computer();
//创建接口的非匿名实现类的非匿名对象
Shubiao s = new Shubiao();
com.m(s);
//创建接口的非匿名实现类的匿名对象
com.m(new Shubiao(););
//创建接口的匿名实现类的非匿名对象
USB phone = new USB(){
public void start(){
System.out.println("手机开始工作");
}
public void stop(){
System.out.println("手机结束工作");
}
};
com.m(phone);
//创建接口的匿名实现类的匿名对象
com.m(new USB(){
public void start(){
System.out.println("MP3开始工作");
}
public void stop(){
System.out.println("MP3结束工作");
}
});
}
}
class Computer{
public void m(USB b){
b.start();
System.out.println("具体工作细节");
b.stop();
}
}
interface USB{
public abstract void start();
public abstract void stop();
}
class Shubiao implements USB{
public void start(){
System.out.println("鼠标开始工作");
}
public void stop(){
System.out.println("鼠标结束工作");
}
}
代理模式
代理模式就是为其他对象提供一种代理以控制对这个对象的访问
代理的对象在提供被代理对象的方法操作之前,进行了一些其他的操作
public class Test{
public static void main(String[] args){
ProxyServe p = new ProxyServe(new Serve());
p.browse();
}
}
interface NetWork{
public abstract void browse();
}
class Serve implements NetWork{
public void browse(){
System.out.println("真实的服务器访问网络");
}
}
class ProxyServe implements NetWork{
private NetWork net;
public ProxyServe(NetWork net){
this.net = net;
}
public void check(){
System.out.println("联网之前先检查");
}
public void browse(){
check();
net.browse();
}
}
工厂模式
实现创建者和调用者的分离
无工厂模式
class Untitled {
public static void main(String[] args){
Car a = new Audi();
a.run();
Car b = new BYD();
b.run();
}
}
interface Car{
public abstract void run();
}
class Audi implements Car{
public void run(){
System.out.println("奥迪跑");
}
}
class BYD implements Car{
public void run(){
System.out.println("比亚迪跑");
}
}
执行结果如下:
简单工厂模式
用来生产同一等级结构的任意产品,实现了调用者和创建者的分离
对于增加新的产品,需要修改已有代码
class Untitled {
public static void main(String[] args){
Car a = CarFactory.getCar("奥迪");
a.run();
Car b = CarFactory.getCar("比亚迪");
b.run();
}
}
//工厂类
class CarFactory{
public static Car getCar(String s){
if("奥迪".equals(s)){
return new Audi();
}else if("比亚迪".equals(s)){
return new BYD();
}
return null;
}
//方式二:
//public static Car getAudi(){
// return new Audi();
//}
//public static Car getBYD(){
// return new BYD();
//}
}
//下面都一样
interface Car{
public abstract void run();
}
class Audi implements Car{
public void run(){
System.out.println("奥迪跑");
}
}
class BYD implements Car{
public void run(){
System.out.println("比亚迪跑");
}
}
执行结果如下:
工厂方法模式
用来生产同一等级结构的固定产品
支持增加任意产品
class Untitled {
public static void main(String[] args){
Car a = new AudiFactory().getCar();
a.run();
Car b = new BYDFactory().getCar();
b.run();
}
}
//工厂接口
interface Factory{
Car getCar();
}
//两个工厂类
class AudiFactory implements Factory{
public Audi getCar(){
return new Audi();
}
}
class BYDFactory implements Factory{
public BYD getCar(){
return new BYD();
}
}
//下面都一样
interface Car{
public abstract void run();
}
class Audi implements Car{
public void run(){
System.out.println("奥迪跑");
}
}
class BYD implements Car{
public void run(){
System.out.println("比亚迪跑");
}
}
执行结果如下:
抽象工厂模式
用来生产不同产品族的全部产品
对于增加新的产品,无能为力。支持增加产品族
练习题
若父类和接口有同名属性,但是子类没有,调用时会报错
但若是子类有同名的参数,则输出的是子类自己的参数
class Untitled {
public static void main(String[] args){
C c = new C();
c.m();
}
}
interface A{
int x = 9;
}
class B{
int x = 10;
}
class C extends B implements A{
public void m(){
//编译报错,因为x是不明确的
//System.out.println(x);
System.out.println(super.x); //10
System.out.println(A.x); //9
}
}
若父类和 父类的父类有同名参数,但是子类没有,则调用的是父类的,就近原则
class Untitled {
public static void main(String[] args){
C c = new C();
c.m();
}
}
class A{
int x = 9;
}
class B extends A{
int x = 10;
}
class C extends B implements A{
int x = 11;
public void m(){
System.out.println(x);
}
}
接口中可以存在的4个结构分别是:
全局常量、抽象方法、静态方法、 默认方法
interface A{
void paly();
}
interface B{
void paly();
}
interface C implements A,B{
Ball ball = new Ball("草莓");
}
class Ball implements C{
private String name;
public Ball(String name){
this.name = name;
}
public String getName(){
return name;
}
public void play(){
//会报错,因为是全局常量,不可修改
//ball = new Ball("西瓜");
System.out.println(ball.getName());
}
}
小结
- 接口中可以定义的结构:
- 全局常量:
public static final
的,可省略不写public static final
- 抽象方法:
public abstract
的,可省略不写public abstract
- 静态方法:通过接口来调用
接口.静态方法
- 默认方法(权限修饰符为 default ):通过实现类的对象来调用
- 全局常量:
- 接口中不可以定义构造器(抽象类有构造器以方便子类继承),意味着接口不可以实例化。开发中,会提供实现类去实现
implements
接口- 实现类实现了一个接口,要么必须重写其中所有的抽象方法,则实现类可以实例化
- 要么,就把自己声明成抽象类。二者必选其一
- 实现类可以实现多个接口,解决了单继承的局限
格式:class AA extends BB implements CC,DD,EE{}
- 接口与接口之间可以继承,而且是!!多继承!!此时实现类就必须重写所有的接口的抽象方法,否则就要声明成抽象类
- 接口的使用也满足多态性
- 接口匿名实现类对象和抽象类的匿名子类对象一样的写法,都用到多态
- 工厂模式:注意方法的重写,子类方法返回值可以是父类方法返回值的子类
- 练习题:若父类和接口有同名属性,但是子类没有,调用时会报错
- 若父类和接口有同名方法,但是子类没有,调用时用的是父类的方法