1.接口
接口(interface)是抽象方法和常量值定义的集合。
接口是实现功能,比如,鼠标、键盘、打印机他们都有usb口,这是他们共同的功能,三者之间并不存在子父类的关系
接口的特点:
用interface来定义。
接口中的所有成员变量都默认是由public static final修饰的。
接口中的所有抽象方法都默认是由public abstract修饰的。
接口中没有构造器。
接口采用多继承机制。

Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections或者Path/Paths这样成对的接口和类。
默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。 我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。 比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认方法。
接口中的默认方法
若一个接口中定义了一个默认方法,而另外一个接口中也定义了一个同名同参数的方法(不管此方法是否是默认方法),在实现类同时实现了这两个接口时,会出现:接口冲突。
解决办法:实现类必须覆盖接口中同名同参数的方法,来解决冲突。
若一个接口中定义了一个默认方法,而父类中也定义了一个同名同参数的非抽象方法,则不会出现冲突问题。因为此时遵守:类优先原则。接口中具有相同名称和参数的默认方法会被忽略。
2.代理模式设计模式
代理设计就是为真实对象提供一种代理以控制对这个对象的访问。
实现步骤:
1.接口,包含要实现的抽象方法
2.被代理类:重写接口的抽象方法,实现真实方法的功能
3.代理类:首先有一个接口的成员变量,然后构造器参数是接口类型的(方便将被代理类传进去),最后重写接口方法,实现被代理类的真实方法
应用场景:
安全代理:屏蔽对真实角色的直接访问。
远程代理:通过代理类处理远程方法调用(RMI)
延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象
比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有
100MB,在打开文件时,不可能将所有的图片都显示出来,这样就可以使用代理
模式,当需要查看图片时,用proxy来进行大图片的打开。
分类
静态代理(静态定义代理类)
动态代理(动态生成代理类)
JDK自带的动态代理,需要反射等知识
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX() {
System.out.println(x);
}
public static void main(String[] args) {
new C().pX();
} }
有问题,编译不通过。
因为x是不明确的,此时父类和接口对于子类来说是同一条线上的。
开发中尽量不要让属性重名。我们在定义属性的时候尽可能的将名字区分开,不要定义重名的
//正确写法
interface A{
int x=0;
}
class B{
int x=1;
}
class C extends B implements A{
public void pX() {
System.out.orintln(super.x);//调用父类的x
//利用接口中的x是全局常量
System.out.println(A.x);//调用接口中的x
}
public static void main(String[] args) {
new C().pX();
}
}
3.内部类
分类:
成员内部类(static成员内部类和非static成员内部类)
局部内部类(不谈修饰符)
匿名内部类
1.成员内部类
成员内部类作为类的成员的角色:
和外部类不同,Inner class还可以声明为private或protected;
可以调用外部类的结构
Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;
成员内部类作为类的角色:
可以在内部定义属性、方法、构造器等结构
可以声明为abstract类 ,因此可以被其它的内部类继承
可以声明为final的
编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)
【注意】
1. 非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员内部类中才可声明static成员。
2. 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
3. 成员内部类可以直接使用外部类的所有成员,包括私有的数据
4. 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的
class Outer {
private int s;//成员变量
public class Inner {//内部类
public void mb() {//内部类的方法
s = 100;
System.out.println("在内部类Inner中s=" + s);
}
}
public void ma() {//外部类的方法
Inner i = new Inner();//创建一个内部类对象
i.mb();//调用内部类的方法
}
}
public class InnerTest {
public static void main(String args[]) {
Outer o = new Outer();//创建一个外部类对象
o.ma();//调用外部类的方法
}
}
2.局部内部类
如何使用局部内部类
只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类
但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类 的父类或父接口类型
局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。
局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
局部内部类不能使用static修饰,因此也不能包含静态成员
public class Test2 {
public void method(){//方法
class A{//方法中的局部类
int age;//局部类的成员变量
public int getAge(){//局部类的方法
return age;
}
}
}
}
3.匿名内部类
匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
格式:
new 父类构造器(实参列表)|实现接口(){
//匿名内部类的类体部分
}
匿名内部类的特点
匿名内部类必须继承父类或实现接口
匿名内部类只能有一个对象
匿名内部类对象只能使用多态形式引用
interface A{
public abstract void fun1();
}
public class Outer{
public static void main(String[] args) {
new Outer().callInner(new A(){
//接口是不能new但此处比较特殊是子类对象实现接口,只不过没有为对象取名
public void fun1() {
System.out.println(“implement for fun1");
}
});// 两步写成一步了
}
public void callInner(A a) {
a.fun1();
}
}
4.面向对象总结

本文介绍了Java中的接口概念及其特点,探讨了接口中的默认方法和静态方法的应用,并详细讲解了代理模式的设计与实现,包括静态代理和动态代理的区别及应用场景。
709

被折叠的 条评论
为什么被折叠?



