接口
当一个类中所有的方法都是抽象方法的时候,我们就可以将其定义为接口
接口也是一种引用数据类型,他比抽象类还抽象。
接口的定义格式:public interface 接口名{}
接口不能被实例化
接口和类之间是实现关系,通过implements关键字表示(区别于extends)
public class 类名 implements 接口名{}
接口的子类(实现类)
要么重写接口中的所有抽象方法
要么是抽象类
接口支持单实现也支持多实现
接口里面的成员变量只能是常量,默认被static final修饰,只能用不能改。而且前边默认有public修饰符不能再加别的权限修饰符。
接口里面没有构造方法
所以实现类中的super()访问的是Object的构造方法,而不是接口中的构造方法。
接口中的方法默认加了abstract
类和接口的比较
如果一个类父类中和实现的接口类中有一个相同的方法,但是具体内容不同,那这个类最后调用的是父类里面的方法。
多态
成员变量:编译看左边,运行看左边(也就是父类中定义的,如果父类中没有定义成员变量而对其调用了,会出现编译错误)
成员方法:编译看左边(父类,就是说在编译阶段如果父类中没有这种成员方法,会提示编译出错),运行看右边(子类)
是什么导致的上述结果呢?因为成员变量没有重写的特点,而成员方法有
多态的好处与坏处:
多态的转型
向下转型,就是Fu f = new Zi();也就是一般的多态定义所以有上面的弊端,不能使用子类的特有功能
向上转型,就是Zi z = (Zi)f; 这里用一个强制类型转换完成,这样就能用子类特有的成员了
多态的转型只能发生在继承和间接继承的关系中,其余都不行
内部类
内部类:就是在一个类中定义一个类。
创建内部类的格式:
内部类可以访问外部类的成员变量,即便成员变量是私有的
按照内部类再类中定义的位置不同,可以分为如下两种形式:
成员内部类,局部内部类
成员内部类
成员内部类既然是成员 那么他就可以被public和private所修饰
只能通过在外部类中设置对内部类的声明和引用,来调用内部类的方法。
静态内部类(也属于成员内部类)
声明方式和一般的不同:
外部类名.内部类名 对象名 = new 外部类名.内部类名
局部内部类
局部内部类是在方法中定义的类,所以外界是无法直接使用的,需要在方法内部创建对象并使用。该类可以直接访问外部类的成员,也可以访问方法内的局部变量。
public class Test4Innerclass {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
class Outer{
int a = 10;
public void method(){
int a = 20;
class Inner{
public void show(){
System.out.println("inner...show");
System.out.println(a);
}
}
Inner i = new Inner();
i.show();
}
}
匿名内部类
概述:匿名内部类本质上是一个特殊的局部内部类(定义在方法内部)
前提:需要存在一个接口或者类
public class Interclass {
public static void main(String[] args) {
new Inter(){
public void show(){
System.out.println("Inter...show");
}
}.show();
}
}
interface Inter{
public void show();
}
对匿名内部类的实现:把继承/实现,方法重写,创建对象,放在一起进行。
如果接口中有多个方法,那么匿名类在实现时,就要用多态的思想去把他实现。
public static void main(String[] args){
Inter2 i2 = new Inter2(){
@Override
public void show1() {
System.out.println("11111");
}
@Override
public void show2() {
System.out.println("22222");
}
};
i2.show1();
i2.show2();
}
interface Inter2{
void show1();
void show2();
}
匿名内部类使用场景:
public class TestSwmming {
public static void main(String[] args) {
goSwimming(new Swimming() {
@Override
public void swim() {
System.out.println("铁子,我们去游泳吧");
}
});
/*
Lambda表达式对匿名内部类进行了优化
* */
goSwimming(()->{
System.out.println("泳子,我们去游铁吧");
});
}
public static void goSwimming(Swimming swimming){
swimming.swim();
}
}
interface Swimming{
public void swim();
}