接口,内部类,局部内部类

总结:
1. 类与类的关系

继承关系,只支持单继承
比如,A是子类 B是父类,A具备B所有的功能(除了父类的私有资源和构造方法)
子类如果要修改原有功能,需要重写(方法签名与父类一致 + 权限修饰符>=父类修饰符)
2. 类和接口的关系

实现关系.可以单实现,也可以多实现
class A implements B,C{}
其中A是实现类,B和C是接口,A拥有BC接口的所有功能,只是需要进行方法的重写,否则A就是抽象类
3. 接口与接口的关系

是继承关系,可以单继承,也可以多继承
interface A extends B,C{}
其中ABC都是接口,A是子接口,具有BC接口的所有功能(抽象方法)
class X implements A{}
X实现类需要重写ABC接口的所有方法,否则就是抽象类
class A extends B implements C,D{}
其中A是实现类,也是B的子类,同时拥有CD接口的所有功能
这时A需要重写CD接口里的所有抽象方法
4. 抽象类与接口的区别

抽象类是一个特殊的类,特殊在,抽象类中可以包含没有方法体的方法(抽象方法)
接口可以理解成一个特殊的抽象类,特殊在,接口里的都是抽象方法,没有普通方法
接口会为方法自动拼接public abstract,还会为变量自动拼接public final static
抽象类可以有成员变量成员常量 接口只能有静态常量
抽象类可以有构造方法–用来给子类创建对象,接口中没有构造方法
抽象类和接口都不能实例化(创建对象)
接口可继承接口,并可多继承接口,但类只能单继承
抽象方法只能声明,不能实现,接口是设计的结果 ,抽象类是重构的结果

复习:

1.接口的特点:

    我们使用interface关键字定义接口
    我们使用implements关键字建立接口实现类与接口的实现关系
    接口是父级,接口实现类是子级
    接口实现类如果实现部分/不实现接口中的抽象方法,那么实现类是一个抽象类
    接口实现类如果实现了接口所有的抽象方法,那么这个实现类是一个普通类
    抽象类与接口都不可以实例化/创建对象
    接口没有构造函数,实现类使用的super()是父类的无参构造
    如果没有明确指定父类,super()代表的才是Object的无参构造
    接口中都是静态常量,没有成员变量,因为会默认拼接public static final
    接口中都是抽象方法,默认会拼接public abstract
    故此:静态常量与抽象方法默认拼接的部分,可以省略不写
    接口不是类!!!
    接口是用来制定规则的【有哪些功能?方法有参数吗?有返回值吗?】
    方法具体的实现交给接口的实现类去完成

2. 接口与类的关系
1.类与类的关系

继承关系,只支持单继承
2.类与接口的关系

实现关系,可以单实现,也可以多实现
class A implements Inter1{}–单实现
class B implements Inter2,Inter3{}–多实现
3.接口与接口的关系

是继承关系,可以单继承,也可以多继承
interface Inter3 extends Inter1{}–接口的单继承
interface Inter4 extends Inter1,Inter2{}–接口的多继承
注意:如果创建接口实现类的话:
Inter3Impl只需要实现接口3与接口1的抽象方法
Inter4Impl不仅需要实现接口4,还需要实现接口4继承自接口1与接口2的所有功能
3. 抽象类与接口的区别:

    抽象类使用class关键字定义,是类
    接口使用interface关键字定义,是接口
    2.抽象类里可以定义成员变量
    接口里没有成员变量,有的是静态常量,默认会拼接public static final
    3.抽象类里的方法不作限制:全普、全抽、半普半抽
    接口中的方法都是抽象方法,默认会拼接:public abstract
    4.抽象类与接口均不可以实例化/创建对象
    5.抽象类里有构造方法,不是为了自己使用,而是为了子类创建对象时调用
    接口里没有构造方法,接口实现类调用的构造是父类的构造方法,与接口无关
    6.接口可以多继承,也就是说,一个接口可以继承一个接口/多个接口
    抽象类只能单继承,也就是说,一个子类只能有一个父类
    7.抽象是后天重构的结果,接口是先天设计的结果
 

package cn.tedu.innerclass;

public class TestInner1 {
    public static void main(String[] args) {
        //在main()方法中创建内部类对象,使用内部类资源
        Outer.Inner oi = new Outer().new Inner();
        oi.delete();
        System.out.println(oi.sum);
         Outer O=new Outer();
         O .find();
    }
}
class Outer{
    String name;
    private  int age;
    public void  find(){
        System.out.println("Outer类的find()");
        /*外部类不可以直接使用内部类的资源,如过想要使用,必须先创建内部类对象*/
        Inner i=new Inner();
        System.out.println(i.sum);
        i.delete();
    }
    /**
     * 根据内部类位置的不同,分为
     * 成员内部类:类里方法外。
     * 局部内部类:方法里
     */
    class Inner{
        int sum=10;
        public void  delete(){
            System.out.println("Inner的delete()");
            /*内部类可以直接使用外部类的资源,包括私有资源*/
            System.out.println(name);
            System.out.println(age);
        }
    }
}


Inner的delete()
null
0
10
Outer类的find()
10
Inner的delete()
null
0
内部类:

1) 内部类可以直接访问外部类中的成员,包括私有成员

2) 外部类要访问内部类的成员,必须要建立内部类的对象

3) 在成员位置的内部类是成员内部类

4) 在局部位置的内部类是局部内部类

总结:

成员内部类被Private修饰以后,无法被外界直接创建对象使用

所以可以创建外部类对象,通过外部类对象间接访问内部类的资源

package cn.tedu.innerclass;

public class TestInner3 {
    public static void main(String[] args) {
        //创建普通内部类对象并调用内部类的功能
//        Outer3.Inner3 oi=new Outer3().new Inner3();
//        oi.show();
//        new Outer3().new Inner3().show();
       /*当成员内部类被static修饰后,new Outer3()外部类对象会报错,
       * 结论:创建静态内部类对象时,不需要先创建外部类对象,直接通过类名调用*/
        Outer3.Inner3 inner3 = new Outer3.Inner3();
        inner3.show();
        new Outer3.Inner3().show();
        //访问静态内部类的静态资源----链式加载
        Outer3.Inner3.show2();
    }
}
class  Outer3{
    //测试成员内部类被static修饰--并不常用
    static class Inner3{
        public void show(){
            System.out.println("Inner3的show()");
        }
        //创建成员内部类的静态方法
        public  static void show2(){
            System.out.println("Inner3的show2()");
        }
    }
}

Inner3的show()
Inner3的show()

总结:

静态资源访问时不需要创建对象,可以通过类名直接访问

访问静态类中的静态资源可以通过”. . . ”链式加载的方式访问

package cn.tedu.innerclass;
/*本类用于测试成员内部类被private修饰*/
public class TestInner2 {
/*如果Inner2被private修饰,无法直接创建对象,该怎么办?*/
public static void main(String[] args) {
    new Outer2().getInner2();
}
}
class Outer2{
    /*提供本类的公共方法,在本方法内部创建内部类的对象,使用内部类的功能*/
    public void getInner2(){
        Inner2 i=new Inner2();
        i.eat();
    }
   private class Inner2{
        public void eat(){
            System.out.println("Inner2的eat()");
        }

   }
}
Inner2的eat()

 局部内部类:

package cn.tedu.innerclass;
/*本类用来测试局部内部类*/
public class Testinner4 {
    public static void main(String[] args){
        /**
         * 如何使用局部内部类的资源呢?
         * 注意:直接调用外部类的show()是无法触发局部内部类的功能的
         * 要执行局部内部类的功能,必须先创建局部内部类的对象并调用对应的功能
         * 创建局部内部类对象,并调用局部内部类的功能
         */
        new Outer4().show();
    }
}
class Outer4{
    //创建外部类的成员方法
    public void show(){
        System.out.println("Outer4的show()");
        class  Inner4{
          String name;
          int age;
          public  void  eat(){
              System.out.println("Inter4的eat()");
          }
        }
        Inner4 in = new Inner4();
        in.eat();
        System.out.println(in.age);
        System.out.println(in.name);
    }
}

Outer4的show()
Inter4的eat()
0
null

匿名内部类没有名字,通常与匿名对象结合在一起使用

匿名对象只能使用一次,一次只能调用一个功能

匿名内部类充当了实现类的角色,去实现接口/抽象类中的抽象方法,只是没有名字而言。

package cn.tedu.innerclass;

public class TestInner5 {
    public static void main(String[] args) {
        //传统方式:创建接口+创建接口实现类+实现类实现接口中所有的抽象方法
        //创建接口实现类的对象+通过对象调用实现了的功能
        /**
         * 创建接口对应的匿名对象与匿名内部类,并调用实现后的save()
         */
        new Inter1() {
            @Override
            public void save() {
                System.out.println("保存");
            }

            @Override
            public void get() {
                System.out.println("获取");
            }
        }.save();
        /**
         * 创建抽象类对应的匿名对象和匿名内部类
         */
        new Inter2(){
            public void  set(){
                System.out.println("set()方法实现了");
            }
        }.set();
        new Inter3().study();

    }
}

interface Inter1 {
    void save();

    void get();
}
abstract class Inter2{
    public void play(){
        System.out.println("玩代码");
    }
   abstract public void set();
}
class Inter3{
    public void study(){
        System.out.println("再冷的天也阻挡不了我学习的热情");
    }
    public void powerUp(){
        System.out.println("我们会越来越强的!                             ");
    }
}


保存
set()方法实现了
再冷的天也阻挡不了我学习的热情

猜你喜欢

转载自blog.csdn.net/weixin_43762083/article/details/120840165