接口
概念:是一种比抽象类还抽象的引用类型。是方法的集合,包含有抽象方法,默认方法,和静态方法。由interface修饰的类。主要作用是弥补Java中的单继承问题。(一个接口可以继承多个接口)
抽象方法:是没有具体实现由abstract修饰的方法,实现接口的实现类必须重写接口中的所有抽象方法。
默认方法:是实现了的方法,实现类可以选择重写默认方法,也可以不重写,实例化的实现类可以直接调用接口的默认方法。其意义在于可以在实现类中对于接口中的默认方法进行升级。由default修饰
简单的举例说明:接口中定义一个默认方法
public default void natural(){
System.out.println("花草树木");
}
我们可以在实现类中重写对默认方法进行升级
public default void natural(){
System.out.println("花草树木");
System.out.println("豺狼虎豹");
}
那么我们在实例化多个实现类时,对于没有特别要求的实现类,统一调用方法是接口中的默认方法,有特殊要求的实现类可自己对方法进行升级。
静态方法:可以通过接口名调用的方法,static关键词修饰。
实现类实现多接口的冲突问题
变量冲突:A,B接口中都有变量a,A接口中还有一个变量b,此时C类实现了A和B接口,我们实例化一个C类可以通过实例化的c直接调用b变量,但不能调用a变量,因为变量冲突实现类就不继承变量。
抽象方法冲突:抽象方法冲突也就是方法名相同,此时只需要实现类重写一次抽象方法就行。
默认方法冲突:默认方法冲突也是方法名相同,但和抽象方法不同的是它会有具体实现,所以此时实现类就必须重写默认方法。
静态方法处理:静态方法是直接通过接口名调用的,没有冲突的情况。
接口继承多接口时的冲突问题
和实现类实现多接口的冲突问题解决方法都一样
实现类继承的父类和接口的冲突问题
基本处理方法也一样,只是抽象方法,和默认方法名字冲突时会调用继承父类中的方法,因为相当于先继承重写了接口中的抽象方法和默认方法。
多态
简单说就是父类的引用指向子类的对象。
例如 Student类是Person的子类Person p= new Student();
多态的前提是继承。是一种向上转型。
好处和弊端:利于扩展,简单例子,当我们不知道一个方法的参数具体时可以先把参数定义为他们的公共父类。 不能调用子类特有的成员。
特点:
1.不能访问子类特有的成员。
2.成员变量冲突时,访问的是父类的成员变量。
3.成员方法冲突时(子类重写了父类方法),访问的是子类的方法。
多态的几种形式
父类引用指向子类对象,抽象父类引用指向子类对象,接口引用指向实现类对象。
多态的几种运用
变量的赋值,方法的参数,方法的返回值
多态的转型
向上转型 :就是最常见的父类引用指向子类对象,弊端和优点就是不能使用子类特有成员,利于扩展。Person p= new Student();
向下转型:将子类引用指向一个创建好的父类引用。(当父类引用指向的对象和当前子类引用类型不匹配回报错)Student s= (Student)person
,所以我们可以在转型之前进行一个判断。
if(person instanceof Student){ //判断对象是不是一个类的示例
`Student s= (Student)personl;
}
内部类
简单概念:定义在一个类内部的类就是内部类
分类:成员内部类,局部内部类,匿名内部类
成员内部类:直接定义在类中的内部类
public class Test {
private String str = "1";
class A{
int c = 0 ;
public void show (){
str = "c";
//成员内部类可以访问所在外部类的成员变量
}
}//A就是一个成员内部类
public static void main(String[] args) {
Test.A s = new Test().new A();
//外部类实例化内部类的方式(外部类不止指声明他的Test类)
s.c = 1 ; //调用内部类的变量
}
}
局部内部类:定义在方法中并在方法中使用的内部类
public class Test {
public void method(){
final String s = "q";
class A{
int a = 0;
String str = s;
//局部内部类想调用方法的成员,成员需要用final修饰
}
A a = new A();//局部内部类只能在方法中使用
System.out.println(a.a);
}
}
匿名内部类:没有名字的类 常用在方法的参数上
格式:new 父类/接口{}
/*
*Animal是一个接口。Cat是实现类
*
*/
public static void main(String[] args) {
Cat cat = new Cat();//正常调用
printAnimal(cat);
printAnimal(new Animal() {//匿名内部类的使用
@Override
public void eat() {
System.out.println("小猫吃鱼2");
}
});
}
public static void printAnimal(Animal animal){
animal.eat();
}
内部类的使用场景:当莫个类除了他的外部类,不再被别的类使用时,也就是内部类依附于外部类而存在的时候,有点像组合的情况。(待扩展)