Java基础之接口与内部类

接 口
 一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。
另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打
印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。继承是一个"是不是"的关系,而接口实现则是 "能不能"
的关系。
 接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守
接口的使用
1.java 中使用interface来定义
2.java 中接口和类是并列的关系
3.如何定义接口,定义接口就是定义接口成员
3.1 JDK7以前:只能定义 全局常量和抽象方法
全局常量:pubic static final的;书写是可以省略
抽象方法:pubic abstract的
JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
4接口不能定义构造器,也就是接口不能实例化
5.java 开发中,接口通过让类实现(implements)的方式来使用
如果实现类覆盖了接口中所有抽象方法,则此实现类可以实例化
如果实现类没有覆盖接口中所有的抽象方法,则此实现类还是一个抽象类
6.java 类可以实现多个接口---->弥补了类的单继承性
格式 calss AA extends BB implement CC,DD{} ---->CC DD 是接口
7.接口与接口之间可以继承而且可以多继承



示例
public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyale.MIN_SPEED);
        System.out.println(Flyale.MAX_SPEED);
        plane p1 = new plane();
        p1.fly();
        plane p2 = new plane();
        p2.fly();
        kite k1 = new kite();
        k1.fly();
        k1.stop();
    }

}
//接口的定义
interface  Flyale{
    //全局常量
    public static final int MAX_SPEED = 7900;//第一宇宙速度
    public  static  final int MIN_SPEED =1;//在接口可以写成int MIN_SPEED =1
    //抽象方法
    public abstract  void fly();//在接口定义的方法也可以这样写void fly();
    //可以省略public abstract
    public abstract void  stop();//在接口定义的方法也可以这样写void stop()

}
class  plane implements  Flyale{
    @Override
    public void fly(){
        System.out.println("通过引擎");

    }
    @Override
    public void stop(){
        System.out.println("通过关闭引擎");
    }
}
class  kite implements  Flyale{
    @Override
    public void fly(){
        System.out.println("依靠风");
    }

    @Override
    public void stop() {
        System.out.println("收好风筝线");

    }
}

  测试结果

1
7900
通过引擎
通过引擎
依靠风
收好风筝线

  示例2

public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyale.MIN_SPEED);
        System.out.println(Flyale.MAX_SPEED);
        plane p1 = new plane();
        p1.fly();
        plane p2 = new plane();
        p2.fly();
        kite k1 = new kite();
        k1.fly();
        k1.stop();
    }

}
//接口的定义
interface  Attackable{
    void attackble();//接口里定义方法
}
interface  Flyale{
    //全局常量
    public static final int MAX_SPEED = 7900;//第一宇宙速度
    public  static  final int MIN_SPEED =1;//在接口可以写成int MIN_SPEED =1
    //抽象方法
    public abstract  void fly();//在接口定义的方法也可以这样写void fly();
    //可以省略public abstract
    public abstract void  stop();//在接口定义的方法也可以这样写void stop()

}
class  plane implements  Flyale{
    @Override
    public void fly(){
        System.out.println("通过引擎");

    }
    @Override
    public void stop(){
        System.out.println("通过关闭引擎");
    }
}
class  kite implements  Flyale{
    @Override
    public void fly(){
        System.out.println("依靠风");
    }

    @Override
    public void stop() {
        System.out.println("收好风筝线");

    }

}
class Bullet  implements Flyale,Attackable{ //一个类可以有多个接口中间使用逗号隔开

    @Override
    public void fly(){

    }
    @Override
    public void  stop(){

    }
    @Override
    public void attackble(){

    }

}
interface AA{

}
interface BB{

}
interface  CC extends AA,BB{ //接口可以定义多个继承的接口,中间使用,号隔开

}

  Java 8 的心特性

Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中
找到像Collection/Collections或者Path/Paths这样成对的接口和类。
默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认方法
JAVA 8的新特性,除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
定义的静态方法只能通过接口去调
定义的默认方法可以通过对象调
接口定义示例
public interface CompareA {
    //静态方法
        public static void method1(){
            System.out.println("北京");
        }
        //默认方法
        public default void method2(){
            System.out.println("上海");
        }
        //默认方法
        default void  method3(){
            System.out.println("深圳");
        }
}

  测试

public class SubClassTese {
    public static void main(String[] args) {
        SubClass s1 = new SubClass();
        //接口定义的静态方法只能通过接口来调用
        CompareA.method1();
        //默认方法通过对象调
        s1.method2();
    }

}
class SubClass implements  CompareA{

}



测试结果
北京
上海

  重写方法

测试

package com.chenxi.Java8;

public class SubClassTese {
    public static void main(String[] args) {
        SubClass s1 = new SubClass();
        //接口定义的静态方法只能通过接口来调用
        CompareA.method1();
        //默认方法通过对象调;如果重写接口方法就是调的重写后的方法
        s1.method2();
    }

}
class SubClass implements  CompareA{
    @Override
    public void method2() {
        System.out.println("杭州");
    }
}


测试
北京
杭州

  如果子类或实现类声明了同名同参的方法,在子类没有重写此方法的情况下;默认去去调父类的方法

  如果实现类实现了多个接口,而多个接口有同名同参的默认方法,那么在实现类没有重写此方法的情况下,报错

接口

public interface CompareA {
    //静态方法
        public static void method1(){
            System.out.println("北京");
        }
        //默认方法
        public default void method2(){
            System.out.println("上海");
        }
        //默认方法
        default void  method3(){
            System.out.println("深圳");
        }
}

  父类

public class SuperClass {
    public void method3(){
        System.out.println("云南");
    }
}

  测试

public class SubClassTese {
    public static void main(String[] args) {
        SubClass s1 = new SubClass();
        //接口定义的静态方法只能通过接口来调用
        CompareA.method1();
        //默认方法通过对象调
        s1.method2();
        //如果子类或实现类声明了同名同参的方法,子类没有重写此方法的情况下;默认去调父类的方法
        s1.method3();//
    }

}
class SubClass extends SuperClass implements  CompareA{
    @Override
    public void method2() {
        System.out.println("杭州");
    }

}
测试
北京
杭州
云南

  内部类

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。
在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者、称为外部类。
 Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
Inner class的名字不能与包含它的外部类类名相同;
分类: 成员内部类(static成员内部类和非static成员内部类)局部内部类(不谈修饰符)、匿名内部类
类的内部类
1.java 允许将一个类A声明在另一个类B中,则A类是内部类,类B外部类
2. 内部类的分类 :成员内部类(静态、非静态)VS 局部内部类(方法内、代码块内、构造器内)
3.成员内部类
作为外部类的成员
调用外部类的属性
可以被4中权限修饰
可以被static 修饰
作为类内部类可以定义属性、方法构造器等
final 修饰 表示不可以被继承
可以被abstract 修饰
关注如下3个问题
如何实例化内部类的对象
如何在成员类中区分调用外部类的结果
局部内类的使用
实例
public class InnerClassTest{
    public static void main(String[] args) {
        //创建Dog 实例(静态的成员内部类)
        Person.Dog dog = new Person.Dog();
        dog.show();
        //创建Bird实例(非静态的成员内部类)
        Person p = new Person();
        Person.Bird bird = p.new Bird();
        bird.sing();


    }

}
class Person{
    String name;
    public Person(){
        //构造器里声明的局部内部类
        class  es{

        }
    }
    public void eat(){
        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 class InnerClassTest1 {
    public void method(){
        class AA{

        }
    }
    public Comparable getComparable(){

        //创建一个实现Comparable接口的类:局部内部类
            //方式1
//        class  MyComparable implements Comparable{
//            @Override
//            public int compareTo(Object o) {
//                return 0;
//            }
//        }
//        return new MyComparable();
        //方式2匿名类的匿名对象
        return new Comparable() {
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }
 }

  



草都可以从石头缝隙中长出来更可况你呢
原文地址:https://www.cnblogs.com/rdchenxi/p/14643154.html