第六章 接口、接口改进(Java8)、内部类
1. interface(接口)
①Java中,接口和类是并列的结构。
②如何定义接口:定义接口中的成员:
a.JDK7及以前:只能定义全局常量和抽象方法
全局常量:声明为public static final的,但是可以不写;
抽象方法:public abstract的,但是可以不写;
b.JDK8:除了定义全局常量和抽象方法外,还可以定义静态方法、默认方法
③接口中不能定义构造器,意味着接口不可以实例化。
④java开发中,接口都通过让类去实现(implements)的方法来使用,如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化;如果实现类没有覆盖接口中的所有抽象方法,则此实现类仍然为抽象类。
⑤Java类可以实现多个接口----弥补了Java类的单继承性的局限性;
格式:class AA extends DD implements BB,CC{}
⑥ 类和类之间:继承关系;类和接口之间:实现关系;接口与接口之间可以继承,而且可以多继承。
⑦接口的使用可以体现多态性;
⑧接口实际上是一种规范。(开发中体会面向接口编程)
public class InterfaceTest {
public static void main(String[] args) {
System.out.println(Flayable.MAX_SPEED);
System.out.println(Flayable.MIN_SPEED);
Plane p1=new Plane();
p1.fly();
}
}
interface Flayable{
//全局常量
public static final int MAX_SPEED=7900;//第一宇宙速度
int MIN_SPEED=1;//省略了public static final
//抽象方法
public abstract void fly();
//省略了public abstract
void stop();
}
class Plane implements Flayable{
@Override
public void fly() {
System.out.println("通过引擎起飞!");
}
@Override
public void stop() {
System.out.println("驾驶员减速停止");
}
}
//如果实现类没有覆盖接口中的所有抽象方法,则此实现类仍然为抽象类
abstract class Kite implements Flayable{
@Override
public void fly() {
}
}
2.Java 8中关于接口的改进
Java 8中,除了定义全局常量和抽象方法外,还可以定义静态方法和默认方法。
①接口中定义的静态方法,只能通过接口来调用;
②通过实现类的对象可以调用接口中的默认方法,如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法;
③如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法,那么子类在没有重写此方法的前提下,默认调用的是父类中声明的同名同参数的方法---->类优先原则;
④如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有实现此方法的前提下,报错----->接口冲突,这就需要我们必须在实现类中重写此方法;
⑤如何在子类(或实现类)的方法中调用父类,接口中被重写的方法;
a.调用自己定义的重写的方法;
b.调用父类中声明的方法;
c.调用接口中的默认方法。
package day62;
/**
* Java 8中,除了定义全局常量和抽象方法外,还可以定义静态方法和默认方法。
* @author 26312
*/
public interface CompareA {
//静态方法
public static void method1() {
System.out.println("CompareA:北京");
}
//默认方法
public default void method2() {
System.out.println("CompareA:上海");
}
default void method3() {
System.out.println("CompareA:上海");
}
}
package day62;
public interface CompareB {
default void method3() {
System.out.println("CompareB:上海");
}
}
package day62;
public class SuperClass {
public void method3() {
System.out.println("SuperClass:北京");
}
}
package day62;
public class SubClassTest {
public static void main(String[] args) {
SubClass subClass=new SubClass();
//1.接口中定义的静态方法,只能通过接口来调用
CompareA.method1();
//2.通过实现类的对象可以调用接口中的默认方法
//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
subClass.method2();
//3.如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法,那么子类在没有重写此方法的
//前提下,默认调用的是父类中声明的同名同参数的方法----类优先原则
//4.如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
//那么在实现类没有实现此方法的前提下,报错-----接口冲突
//这就需要我们必须在实现类中重写此方法
subClass.method3();
}
}
class SubClass extends SuperClass implements CompareA,CompareB{
public void method2() {
System.out.println("SubClass:上海");
}
public void method3() {
System.out.println("SubClass:深圳");
}
//5.如何在子类(或实现类)的方法中调用父类,接口中被重写的方法
public void mymethod() {
method3();//调用自己定义的重写的方法
super.method3();//调用父类中声明的方法
CompareA.super.method3();//调用接口中的默认方法
CompareB.super.method3();
}
}
3.类的成员之五:内部类
①Java中允许将一个类A声明在类B中,则类A就是内部类,类B称为外部类;
②内部类的分类:成员内部类(静态的、非静态的)vs局部内部类(方法内,代码块内,构造器内)
③成员内部类:一方面,作为外部类的成员,调用外部类的结构;可以被abstract修饰;可以被四种不同的权限修饰;另一方面,作为一个类,类内可以定义属性、方法,构造器等;可以被final修饰,表示此类不能被继承;言外之意,不使用final,就可以被继承;可以被abstract修饰。
package day63;
class Person{
String name="小明";
int age;
public void eat() {
System.out.println("人吃饭");
}
static class Dog{//静态成员内部类
String name;
int age;
public void show() {
System.out.println("卡拉是条狗!");
}
}
class Bird{//非静态成员内部类
String name="杜鹃";
public Bird() {
}
public void sing() {
System.out.println("我是一只小小鸟!");
Person.this.eat();//调用外部类的结构
}
public void display(String name) {
System.out.println(name);//方法形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
}
}
public void metho() {
class AA{//局部内部类
}
}
{
class BB{//局部内部类
}
}
public Person() {
class CC{//局部内部类
}
}
}