day09 抽象类、匿名内部类

  • JavaSE
  • JavaSE
约 1352 字

抽象类

package note;

public class AbstractNote {//抽象方法和抽象类
    public static void main(String[] args) {
        //region
        /*
        抽象类不能实例化(不能创建对象),必须由其实现类(子类)实例化
        为什么不能实例化?
        没有一个对象叫动物,他没有具体的属性,(动物几只脚、有没有毛)
         */
//        new Animal();
        //endregion
    }
}

abstract class Animal {
    //region 抽象方法
    /*
    当某个父类某个方法根据子类的不同而有不同的实现,且父类不能实现该方法时,此方法应该定义为抽象方法
    方法后的{}即为该方法的实现
     */
    public abstract void eat();
    //endregion

    public void show() {//抽象类可以有非抽象方法
        System.out.println("我属于动物");
    }

}

class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("吃骨头");
    }
}

接口

package note;

public class InterfaceNote {//接口
    public static void main(String[] args) {

    }
}

interface usb {
    //region 成员变量
    /*
    接口中的所有属性都默认由static final 修饰(都是静态常量)
     */
//    public String name;因为被final修饰,所以必须赋初值
    //endregion

    //region 成员方法
    /*
    接口里面的所有方法都默认由 abstract 修饰(都是抽象方法)
     */
    public void read();
    //endregion

    //region 接口中可以有实现方法,他们必须由static或者default修饰
    public default void method () {

    }
    public static void method1 () {

    }
    //endregion

    //endregion
}

抽象类和抽象方法

当关注一个对象的本质时用抽象类,当关注这个对象有哪些功能时用接口

不同点

  • 抽象类:
    • 可以有非静态属性
    • 可以有构造方法
    • 抽象方法必须用 abstract 修饰
    • 抽象类的实现方法不需要特别的声明
    • 仅支持单继承 (类与类之间不能多继承,接口与接口之间可以实现多继承)
  • 接口:
    • 属性只能是静态的常量
    • 没有构造方法
    • 抽象方法不需要特别声明
    • 接口中的实现方法必须通过 default 或者 static 修饰
    • 可以多实现

共同点

  • 都不能直接创建对象
  • 一般都包括抽象方法

注意:接口不能实现接口 (接口里面不能有实现方法)

内部类

  • 使用场景:当 B 类只为 A 类提供服务,B 类只会在 A 类中使用到,这个时候就可以把 B 类做成 A 类的内部类
package note;

public class InnerClassNote {//内部类

    public static void main(String[] args) {
        Outer outer = new Outer();


        //region 非静态内部类
        Outer.Inner inner = outer.new Inner();
        System.out.println(inner.age);
        //endregion

        //region 静态内部类
        Outer.StaticInner staticInner = new Outer.StaticInner();
        System.out.println(staticInner.name);
        System.out.println(Outer.StaticInner.age);
        //endregion
    }
}

//region
/*
内部类:一个类的声明在另一个类里面
    非静态内部类:当做非静态方法对待
    静态内部类:当做静态方法对待
外部类:包含内部类的类
Inner类的class文件名为:Outer$Inner.class
 */
class Outer {
    class Inner {
        //region 在非静态内部类中不能包含静态方法和静态变量
//        public static int age;
//        public static void methodStaticInner() {
//
//        }
        //endregion
        public int age;

        public void methodInner() {
            System.out.println("非静态方法内部类");
        }
    }

    static class StaticInner {
        //region 在静态内部类中能包含静态方法和静态变量
        public static int age;
        public static void methodStaticInner() {
            System.out.println("静态内部类静态方法");
        }
        //endregion

        public String name;

        public void methodInner() {
            System.out.println("静态内部类非静态方法");
        }
    }
}
//endregion

局部内部类、成员内部类

package InternalClass;
//编译生成的class文件为Outer.class 和 Outer$Inner.class 两个文件
public class Outer {
    public int num = 10;
    public String name;
    public class Inner{//成员内部类,定义在类里面的类
        public int num = 20;
        public void innerMethod() {
            int num = 30;
            System.out.println("内部方法执行");
            System.out.println(name);//内部类可以访问外部类的成员变量
            System.out.println(num);
            System.out.println(this.num);//访问本类
            System.out.println(Outer.this.num);//访问外部类
        }
    }

    public void outerMethod() {
        System.out.println("外部方法执行");
        new Inner().innerMethod();//间接执行内部类方法
        final int num = 40;//在局部内部类使用的时候最好用final关键字修饰
        class OuterMethodInner {//局部内部类,定义在方法中的,只能在方法中创建实例对象
            void outerMethodInnerMethod() {
                System.out.println("局部内部类执行"+num);//局部内部类要想使用局部变量,必须使得变量不可变,因为局部内部类的生命周期比局部变量长。
            }
        }
        OuterMethodInner method = new OuterMethodInner();
        method.outerMethodInnerMethod();
    }
}
package InternalClass;

public class OuterMain {
    public static void main(String[] args) {
        Outer outer= new Outer();
        outer.outerMethod();

        System.out.println("==============");

        Outer.Inner inner = new Outer().new Inner();//直接使用内部类
        inner.innerMethod();
    }
}

匿名内部类

  • 主要针对于抽象类、接口来阐述
package note;

/**
 * 匿名内部类
 */
public class AnonymousInnerClassNote {

    public static void main(String[] args) {
        //region 匿名内部类的使用
        /*
        该匿名内部类的字节码文件名为:
        AnonymousInnerClassNote$1.class
        该匿名类只能在本类中使用(AnonymousInnerClassNote)
         */
        A a = new A() {
            @Override
            public void methodA() {
                System.out.println("匿名内部类执行A");
            }
        };
        a.methodA();

        /*
        该匿名内部类的字节码文件名为:
        AnonymousInnerClassNote$2.class
        该匿名类只能在本类中使用(AnonymousInnerClassNote)
         */
        new B(){
            @Override
            public void methodB() {
                System.out.println("匿名内部类执行B");
            }
        }.methodB();
        //endregion
    }
}

abstract class A{
    public abstract void methodA();
}

interface B{
    void methodB();
}

强制转型

package note;

public class CoercionNote {//强制转型
    public static void main(String[] args) {
        //region 父类引用指向子类对象
        Person person = new Student();//发生了向上转型
//        person.stucode;不能使用子类的属性
//        person.study;不能使用子类的方法
        //endregion

        //region 向下转型
        Student student = (Student) person;//当该变量本身就引用子类的对象时才可以向下转型
        //endregion
    }
}

class Person {
    String name;
    int age;
    public void show () {
        System.out.println(name + ","+age);
    }
}

class Student extends Person{
    int stucode;
    public void study() {
        System.out.println("学习");
    }
}
上次编辑于:
贡献者: Noby338,noby