static、接口、多态、内部类

static、接口、多态、内部类

昨日重点内容回顾

* 类的继承格式
		public class Fu{
            
		}	
		public class Zi extends Fu{
            
		}
* 继承的特点
        ① 一个类只能有一个直接父类!【单继承】
        ② 一个父类可以有多个子类!
        ③ Java里面允许多级继承!
        ④ 父类拥有的子类全部都直接继承(拥有)【不能继承父类的私有成员和构造方法】
        ⑤ Object类是java的顶层父类

* 子类调用父类的成员特点
	* 成员变量
    	子类与父类成员变量未重名:通过变量名称来识别访问的是父类的还是子类的!
    	子类与父类成员变量重名:默认访问的是子类的成员变量,可以通过this明确指定访问子类,通过super访问父类
    * 成员方法
		子类与父类成员方法未重名:通过方法名称来识别访问的是父类的还是子类的!
		子类与父类成员方法重名:默认访问的是子类的成员方法,可以通过this明确指定访问子类,通过super访问父类
		
* 方法重写的概念
	一旦子类与父类的成员方法重名,就构成了方法覆盖重写!===>>> 可以在子类中父类的方法进行增强!
	构成方法覆盖重写的条件:
		① 存在继承或者实现关系
		② 方法的签名必须完全一致!【除了访问权限修饰符以外,子类必须不得低于父类的访问权限修饰符的范围】
		
* this可以解决的问题
	① 区分成员变量和局部变量(重名)
	② 区分是子类的内容还是父类的内容!
	
* super可以解决的问题
	区分是子类的内容还是父类的内容!【代表的是父类!】

* 抽象方法的概念
	没有方法体的方法就是抽象方法!

* 抽象类的格式
	被abstract修饰的类就是一个抽象类!一个类中有抽象方法,这个类必定是一个抽象类!

* 抽象方法的格式
	访问权限修饰符 abstract 返回值数据类型 方法名称(参数列表);
		public abstract void method();

* 父类抽象方法的存在意义
	供子类继承,然后去覆盖重写!=====>>> 模板设计模式!

* final修饰的类的特点
	被final修饰的类不能被继承!	

* final修饰的方法的特点
	被final修饰的方法不能被覆盖重写

* final修饰的变量的特点
	① 修饰成员变量:它其实是一个常量(一般常量名全部大写),必须初始化值(其值不能被修改)!
	② 修饰局部变量:
		基本数据类型:不能二次赋值!
		引用数据类型:不能修改地址值,但是可以修改里面的数据!	

今日内容介绍

* static关键字
* 接口
* 多态
* 内部类

学习目标

* 能够掌握static关键字修饰的变量调用方式
		类名.变量名称  【一般类变量使用private修饰,外界无法直接方法】
* 能够掌握static关键字修饰的方法调用方式
		类名.方法名称(参数列表);
* 能够写出接口的定义格式
		public interface 接口名称{
            
		}
* 能够写出接口的实现格式
		public class 类名 implements 接口名称{
            
		}
* 能够说出接口中的成员特点
	①抽象方法:
		需要实现类去重写,然后通过实现类的对象去调用!
    ②静态方法:
    	直接通过接口名称去调用!
    ③默认方法:
    	根据需要选择性的去重写(不是必须的),通过实现类的对象去调用!

* 能够说出多态的前提
* 能够写出多态的格式
* 能够理解多态向上转型和向下转型
* 能够说出内部类概念
* 能够理解匿名内部类的编写格式
		接口名称 对象 = new 接口名称+回车!

一、static关键字【重点】

static是静态修饰符,一般修饰成员(成员变量、成员方法、代码块)。

public class Student {
    // 成员变量
    // 姓名
    private String name;
  
    // 成员方法
    public void study(){
        System.out.println("good good study,day day up!");
    }    
}

类中的成员变量是每个对象独有的!成员方法是类中多个对象所共有的!===>>> 对象级别的!

一旦我们使用static对成员变量或者成员方法进行修饰,那么这个成员变量(类变量)和成员方法(类方法)就不再属于某个对象了,它已经是一个类级别的了!**static修饰的成员被多个对象共享。**static修饰的成员属于类,但是会影响每一个对象。被static修饰的成员又叫类成员,不叫对象的成员。

1.1 static修饰成员变量

/**
	姓名、年龄:多个对象独自拥有自己的数据!
	所在教室:多个学生对象共同拥有!
*/
public class Student {

    // 成员变量
    // 姓名
    private String name;

    // 年龄
    private int age;

    // 班级教室
    static String classRoom = "天津203";

    // 成员方法
    public void study(){
        System.out.println("good good study,day day up!");
    }


    // 成员方法
    public void show(){
        System.out.println("姓名:"+ name + ", 年龄:"+ age+", 所在班级:"+ classRoom);
    }

    public Student() {

    }

    public Student(String name, int age, String classRoom) {
        this.name = name;
        this.age = age;
        this.classRoom = classRoom;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getClassRoom() {
        return classRoom;
    }

    public void setClassRoom(String classRoom) {
        this.classRoom = classRoom;
    }

}
/**
	类变量(static修饰的成员变量),被多个对象共享数据!
	所有对象都相同的默认值!只要有一个对象对其值进行修改,那么其余对象拿到的都是修改之后的数据!
*/
public class StudentDemo {

    public static void main(String[] args) {
        // 创建学生对象
        Student s1 = new Student();
        s1.setName("jack");
        s1.setAge(38);
        // 修改所在教室!
        //s1.setClassRoom("天津205");
        Student.classRoom="天津205"; // 类变量通过类名访问
        s1.show();

        // 创建学生对象
        Student s2 = new Student();
        s2.setName("rose");
        s2.setAge(18);
        s2.show();

    }
}

当 static 修饰成员变量时,该变量称为类变量。该类的每个对象都共享同一个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。

在这里插入图片描述

1.2 static修饰成员方法

成员方法:属于对象级别的!【操作成员方法,通过对象来调用】
静态方法:属于类级别的!【操作静态方法,通过类名来调用】

/*
    static关键字:修饰成员方法=====>>> 静态方法!
 */
public class Student {

    // 成员变量
    private String name;

    // 成员方法
    public void show(){
        System.out.println("姓名:"+ name);
    }

    // 静态方法
    public static void study(){
        System.out.println("好好学习,天天向上!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class StudentDemo {

    public static void main(String[] args) {
        // 创建学生对象
        Student student = new Student();
        student.setName("jack");
        // 通过对象调用成员方法
        student.show();

        // 类名调用静态方法【静态方法在哪个类中,那么就使用哪个类名来调用】
        Student.study();
    }
}

1.3 静态方法与成员方法相互调用的规则

/*
    静态方法与成员方法的相互调用规则:
        成员方法属于对象级别,需要通过对象来调用!
        静态方法属于类级别,直接通过类名来调用!

        * 成员方法里面可以直接调用成员方法,还可以直接调用静态方法
        * 静态方法里面可以直接调用静态方法,不能直接调用成员方法

 */
public class Demo01 {

    // 类变量
    private static int number = 10;
    // 成员变量
    private int count = 100;

    // 成员方法
    public void method1(){
        System.out.println("么么哒!");
        // 调用成员方法
        method2();
        // 调用静态方法
        method3();
        // 访问成员变量
        System.out.println(count);
        // 访问类变量
        System.out.println(number);
    }

    // 成员方法
    public void method2(){
        System.out.println("呵呵哒!");
    }

    // 静态方法
    public static void method3(){
        System.out.println("晕晕哒!");
    }

    // 静态方法
    public static void method4(){
        System.out.println("蒙蒙哒!");
        // 调用静态方法
        method3();
        // 调用成员方法
        // method2();  // 编译报错!
        // 访问成员变量
        //System.out.println(count); // 编译报错!
        // 访问类变量
        System.out.println(number);
    }

    // 测试方法
    public static void main(String[] args) {
        // 创建对象
        Demo01 demo01 = new Demo01();
        // 调用方法
        //demo01.method1();

        // 类名调用
        Demo01.method4();
    }
}

结论
非静态的,可以访问静态的,也可以访问非静态的!【在成员方法中,可以访问静态方法和类变量,还可以访问成员方法和成员变量】
​ 静态的,只能访问静态的!【在静态方法中,只能访问静态方法和类变量】

二、接口【重点】

2.1 接口的概念和基本操作

* 普通类里面一般有:成员变量和成员方法
* 抽象类:成员变量、成员方法、抽象方法
不管是普通类还是抽象类,都是类!而学习面向对象时我们知道类主要描述 属性和行为!===>>> 希望行为(功能方法)是确定实现的!
而实际需求,是需要使用到抽象方法的!而又不建议在类中定义!=======>>>> 干脆将所有的抽象方法单独定义在一个内容(接口)中!

接口:它是一个规定(规范),只有约定,没有实现!=====>>>> 抽象方法(有方法的描述,没有方法的具体实现)

* 接口:
	它是一种引用数据类型(数组、类、接口),接口里面主要是方法的集合(主要针对抽象方法)
	
* 如何定义接口
        public interface 接口名称{
            // 主要定义抽象方法(也可以定义其它方法)
        }

* 接口的使用
	主要是供子类去实现!(需要覆盖重写接口里面所有的抽象方法)

2.2 接口里面定义方法

public interface MyInterface {

    // 抽象方法
    public abstract void method1();

    // 抽象方法
    abstract void method2();

    // 抽象方法
    void method3();

    // 静态方法
    public static void method4(){
        System.out.println("接口中的静态方法执行了1。。。");
    }

    // 静态方法
    static void method5(){
        System.out.println("接口中的静态方法执行了2。。。");
    }

    // 默认方法
    public default void method6(){
        System.out.println("接口中的默认方法执行了1。。。");
    }

    // 默认方法
    default void method7(){
        System.out.println("接口中的默认方法执行了2。。。");
    }

    // jdk9开始支持!
    /*private void method8(){
        System.out.println("私有方法!");
    }*/

}

2.3 接口的实现

接口:规范,约定!只做了说明,没有实现!======>>>> 供其它类来实现的 !

类与类之间是继承关系! extends
类与接口之间是实现关系!implements 【实现类需要将接口中所有的抽象方法全部实现!】

/*
    类与类之间是继承关系! extends
    类与接口之间是实现关系!implements

    实现类需要实现接口里面所有的抽象方法
    实现类需要实现接口里面所有的抽象方法,接口中的默认方法将会被继承到实现类
 */
public class MyInterfaceInstance  implements MyInterface{
    @Override
    public void method1() {
        System.out.println("抽象方法1的实现!");
    }

    @Override
    public void method2() {
        System.out.println("抽象方法2的实现!");
    }

    @Override
    public void method3() {
        System.out.println("抽象方法3的实现!");
    }

}
/*
    测试类!
        接口中的抽象方法:通过接口实现类的对象去调用!
        接口中的静态方法:通过接口名称去调用!
        接口中的默认方法:通过接口实现类的对象去调用!
 */
public class Test {

    public static void main(String[] args) {

        // 创建实现类的对象
        MyInterfaceInstance instance = new MyInterfaceInstance();
        // 调用抽象方法【调用实现类中实现好的方法】
        instance.method1();
        instance.method2();
        instance.method3();

        // 调用接口中的静态方法(通过接口名称)
        MyInterface.method4();
        MyInterface.method5();

        // 调用接口中的默认方法
        instance.method6();
        instance.method7();
    }
}

2.4 接口的特点

① 接口与类的关系

	① 类与类之间是继承关系!  extends(继承)
	② 类与接口之间是实现关系! implements(实现)
	③ 接口与接口之间是继承关系!

② java中的类是单继承,但是接口可以多继承!

public interface A{
    void methodA1();
}
public interface B {
    void methodB1();
}
public interface C extends A,B{
    void methodC1();
}
public class AInstance implements C {

    @Override
    public void methodA1() {

    }

    @Override
    public void methodB1() {

    }

    @Override
    public void methodC1() {

    }
}

③ 一个接口可以有多个实现类

public interface A {
    void methodA1();
}
public class B implements A{
    @Override
    public void methodA1() {
		//  空实现!
    }
}
public class C implements A {
    @Override
    public void methodA1() {

    }
}

④ 接口也支持多级继承

public interface A {

}
public interface B extends A {

}
public interface C extends B {

}

⑤ 一个类可以继承唯一的一个父类,然后同时实现多个接口

public interface A {

    // 抽象方法
    void methodA1();

    // 抽象方法
    void methodA2();

    // 默认方法
    default void methodA3(){
        System.out.println("接口A里面的默认方法3");
    }

    // 默认方法
    default void methodA4(){
        System.out.println("接口A里面的默认方法4");
    }

    // 静态方法
    public static void methodA5(){
        System.out.println("接口A里面的静态方法5");
    }

    // 静态方法
    public static void methodA6(){
        System.out.println("接口A里面的静态方法6");
    }
}
public interface B {

    // 抽象方法
    void methodA1();

    // 抽象方法
    void methodB2();

    // 默认方法
    default void methodA3(){
        System.out.println("接口B里面的默认方法3");
    }

    // 默认方法
    default void methodB4(){
        System.out.println("接口B里面的默认方法4");
    }

    // 静态方法
    public static void methodB5(){
        System.out.println("接口B里面的静态方法5");
    }

    // 静态方法
    public static void methodB6(){
        System.out.println("接口B里面的静态方法6");
    }

}
public abstract class C {

    // 成员方法
    public void methodC1(){
        System.out.println("类C里面的成员方法执行了。。。");
    }

    // 抽象方法
    public abstract void methodC2();

    // 抽象方法
    public abstract void methodC3();

    // 抽象方法
    public abstract void methodA1();

    public void methodA4(){
        System.out.println("类C里面的methodA4方法执行了!");
    }

}
/*
    一个类继承唯一的一个父类,实现多个接口!
        * 必须实现多个接口里面所有的抽象方法
            多个接口(父类)中有重名的抽象方法,只需要重写一次!未重名的全部实现!

        * 多个接口的默认方法:【根据需要来重写,不是强制!】
            重名的只需要重写一次!其它的根据需要而定!

        * 静态方法:通过接口名称来调用,非常容易识别是哪个接口里面的静态方法
 */
public class D extends C implements B,A{

    @Override
    public void methodA1() {

    }

    @Override
    public void methodA2() {

    }


    @Override
    public void methodB2() {

    }

    @Override
    public void methodA3() {

    }

    /*@Override
    public void methodA4() {

    }*/


    @Override
    public void methodB4() {

    }

    @Override
    public void methodC2() {

    }

    @Override
    public void methodC3() {

    }

    public static void main(String[] args) {
        D d = new D();
        d.methodA4();
    }
}

2.5 接口中其它成员

① 接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰。

② 接口中,没有构造方法,不能创建对象。

③ 接口中,没有静态代码块。

/*
    在接口中不允许:
        1.定义成员变量(定义为常量,是public static final修饰)
        2.不能提供构造方法
        3.不能书写静态代码块
 */
public interface Demo02 {

    public static final  int NUMBER=10;

    /*public Demo02(){

    }*/

    /*static{

    }*/

}

2.6 接口案例

* 通过实例进行分析和代码演示抽象类和接口的用法。   
   * 犬:
        行为:
            吼叫;
            吃饭;
   * 缉毒犬:
        行为:
            吼叫;
            吃饭;
			缉毒;    	

分析:

在这里插入图片描述

/*
    具备缉毒功能的接口
 */
public interface JiDu {

    // 缉毒功能的抽象方法
    void jiDu();

}
/*
    抽象父类
 */
public abstract class QuanKe {

    // 吼叫
    public abstract void houJiao();

    // 吃饭
    public abstract void eat();
}
/*
    它是一个犬科类!
 */
public class Pig extends QuanKe{

    @Override
    public void houJiao() {
        System.out.println("猪在叫。。。");
    }

    @Override
    public void eat() {
        System.out.println("猪在吃饲料。。。");
    }
}
/*
    它是一种犬科类动物,还具备缉毒功能!
 */
public class JiDuDog extends QuanKe implements JiDu{

    @Override
    public void houJiao() {
        System.out.println("缉毒狗在狂叫。。。");
    }

    @Override
    public void eat() {
        System.out.println("缉毒狗在吃肉。。。");
    }

    @Override
    public void jiDu() {
        System.out.println("缉毒狗正在缉毒。。。");
    }
}
/*
    测试类:
 */
public class Test {

    public static void main(String[] args) {

        // 创建对象
        Pig pig = new Pig();
        pig.houJiao();
        pig.eat();
        System.out.println("===========");

        // 创建对象
        JiDuDog dog = new JiDuDog();
        dog.houJiao();
        dog.eat();
        dog.jiDu();

    }
}

2.7 接口的好处(补充)

接口是一个规范(只是定义了功能的描述,没有提供具体的实现)====>>>> 谁要使用我这个功能,你就要实现接口中的这些抽象方法!

在实际开发中,一个大的项目一般是由一个团队(很多开发人员)来开发的,需要分工。可能存在这种现象:
A 开发了一个模块(里面有很多小功能),但是在实现这个功能的过程中,需要使用B里面的某个功能!但是B它没有实现这个功能,不能让A等着!!!可以将这个功能定义在接口中,不提供具体的实现,只提供功能的描述!A 直接调用接口里面的这个方法就行了。具体的这个实现让B后面有时间再补上!

也就说,使用接口,能够方便多人(团队)开发!还可以实现代码的解耦!

三、多态【重难点】

3.1 多态概念

字面意义:一个对象呈现的多种形态!

* 具体的一个人====>>>> 张杰 (对象)
	站在他媳妇的面前,他就是丈夫的形态!
	站在他爹的面前,它就是儿子的形态!

Java中的多态必须有前提条件:

① 必须存在继承或者实现的关系!

② 保证有意义,存在覆盖重写!

3.2 多态体现

多态体现一: 父类引用指向子类对象!

/*
    父接口
 */
public interface Animal {

    // 抽象方法
    void eat();

}
/*
    实现类
 */
public class Cat implements Animal{

    // 重写父接口的抽象方法
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }

}
/*
    测试类:
 */
public class Test {

    public static void main(String[] args) {

        // 创建对象(接口不能创建对象!)
        //Cat cat = new Cat();
        // Animal:动物!  Cat: 猫  =====>>> 猫(new Cat)是猫! 猫(new Cat)是一个动物!【用动物来标识猫(new Cat)】
        Animal cat = new Cat();  // 父类(接口)引用(cat)指向了子类的对象(new Cat())!
        cat.eat();

    }

}

多态体现二:在方法的形参位置,使用父类(接口)类型

/*
    父接口
 */
public interface Animal {

    // 抽象方法
    void eat();

}
/*
    实现类
 */
public class Dog implements Animal{

    @Override
    public void eat() {
        System.out.println("狗吃骨头!");
    }
}
/*
    实现类
 */
public class Cat implements Animal {

    // 重写父接口的抽象方法
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }

}
/*
    测试类:
 */
public class Test {

    public static void main(String[] args) {

        // 创建对象(准备实参)
        Cat cat = new Cat();  // 父类(接口)指向了子类的对象!
        Dog dog = new Dog();

        // 调用静态方法
        eat(cat);

    }

    /*
    // 定义方法:猫吃东西的功能
    public static void eat(Cat cat){
        // 此方法没有定义具体的功能实现,而是直接调用传递进来对象原本的功能
        cat.eat();
    }

    // 定义方法:狗吃东西的功能
    public static void eat(Dog dog){
        dog.eat();
    }*/

    public static void eat(Animal animal){  // 参数形参使用父类(接口)类型
        animal.eat();
    }

}

多态体现三:在方法的返回值数据类型位置,使用父类(接口)类型

* Animal、Cat、Dog的代码与体现二的代码完全一致!
/*
    测试类:
 */
public class Test {

    public static void main(String[] args) {

        // 创建对象(准备实参)
        Animal animal = getAnimal();

        // 调用eat方法
        animal.eat();

    }

    /*
    // 定义方法:获得一只猫(对象)
    public static Cat getCat(){
        Cat cat = new Cat();
        return cat;
    }

    // 定义方法:获得一条狗(对象)
    public static Dog getDog(){
        Dog dog = new Dog();
        return dog;
    }
    */

    // 返回一个动物 【方法的内部实现以后是可以让其固定不变,通过配置文件来觉得创建哪个子类对象】
    public static Animal getAnimal(){ // 方法返回值类型指定为父类(接口)类型
        // 创建一个Cat
        Cat cat = new Cat();
        // 创建一个Dog
        Dog dog = new Dog();
        return dog;
    }


}

3.3 多态好处

让代码更加通用(提高了扩展性)!代码演示:多态体现二!

3.4 引用类型转型

/*
    父接口
 */
public interface Animal {

    // 抽象方法
    void eat();

}
/*
    实现类
 */
public class Dog implements Animal {

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

    // 提供额外功能
    public void watchHose(){
        System.out.println("狗看家!");
    }
}
/*
    实现类
 */
public class Cat implements Animal {

    // 重写父接口的抽象方法
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }

    public void catchMouse(){
        System.out.println("猫捉老鼠!");
    }

}

/*
    测试类:
 */
public class Test {
    public static void main(String[] args) {

        /*
            // 使用多态创建对象
            Animal animal = new Cat(); // animal是一只猫 【向上转型:安全!】

            // 调用方法
            animal.eat();
            // 编译报错: 编译阶段看左边(创建对象等号左边),它是一个Animal类型的,而在Animal没有这个方法!
            //animal.catchMouse();
            // 向下转型 【不一定安全!】
            Cat cat = (Cat)animal;
            cat.catchMouse();
        */

        // 使用多态创建对象
        //Animal animal = new Cat();
        Animal animal = new Dog();
        // 编译看左边(Animal里面有这个方法,编译通过!),运行看右边!
        animal.eat();

    }
}

问题:什么时候需要向下转型?

当需要调用子类自己独有功能的时候,需要向下转型!【可能存在安全问题!】

/*
    父接口
 */
public interface Animal {

    // 抽象方法
    void eat();

}
/*
    实现类
 */
public class Cat implements Animal {

    // 重写父接口的抽象方法
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }

    public void catchMouse(){
        System.out.println("猫捉老鼠!");
    }

}
/*
    实现类
 */
public class Dog implements Animal {

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

    // 提供额外功能
    public void watchHose(){
        System.out.println("狗看家!");
    }
}
/*
    测试类:
 */
public class Test {
    public static void main(String[] args) {

            // 使用多态创建对象
            Animal animal = new Dog(); // animal是一条狗 【向上转型:安全!】

            // 调用方法
            animal.eat();
            // 编译报错: 编译阶段看左边(创建对象等号左边),它是一个Animal类型的,而在Animal没有这个方法!
            // animal.catchMouse();
            // 向下转型 【不一定安全!】
			Cat cat = (Cat)animal; // 运行时异常!animal是Dog类型,非得强转为Cat类型!
            cat.catchMouse();

    }
}

在这里插入图片描述

添加判断,增强程序的健壮性!

/*
    测试类:
 */
public class Test {
    public static void main(String[] args) {

            // 使用多态创建对象
            Animal animal = new Dog(); // animal是一条狗 【向上转型:安全!】

            // 调用方法
            //animal.eat();
            // 编译报错: 编译阶段看左边(创建对象等号左边),它是一个Animal类型的,而在Animal没有这个方法!
            // animal.catchMouse();
            // 向下转型 【不一定安全!】

            // 添加判断,增强程序的健壮性!
            if(animal instanceof Cat){ // animal它是一个Cat类型的么?
                // 向下转型为Cat
                Cat cat = (Cat)animal;
                cat.catchMouse();
            }else if(animal instanceof Dog){
                // 向下转型为Dog
                Dog dog = (Dog) animal;
                dog.watchHose();
            }
    }
}

四、内部类

4.1 内部类概念

在一个类的内部定义一个类,就是内部类!

4.2 成员内部类

在一个类的成员位置定义另外一个类,那么另外的那个类就是成员内部类!

/*
    内部类:
        在一个类Outer的内部再去定义另外一个类Inner!Inner类如果在Outer类的成员位置,它就是一个成员内部类!

    一个Java文件可以定义多个类
        平级:可以存在N个类!只有一个类能够被public修饰(被public修饰的这个类的类名与文件名称一致的)!

 */
public class Outer {

    // 成员位置(定义成员变量、成员方法、成员内部类)
    // 成员变量
    private boolean live = true;

    // 定义成员方法
    public void show(){

    }

    // 定义成员内部类
    class Inner{

        // 定义方法
        public void Heart(){
            // 判断
            if(live){
                System.out.println("心脏在跳动,可以存活!");
            }else{
                System.out.println("心脏停止跳动,挂了!");
            }
        }

    }

}

问题:如何创建成员内部类的对象呢?

* 创建内部类对象的格式:
	外部类名.内部类名 对象名 = new 外部类名().new 内部类名()
/*
    创建成员内部类的格式:外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
 */
public class Test {

    public static void main(String[] args) {

        // 创建Outer类对象
        Outer outer = new Outer();

        // 创建Inner类的对象
        //Outer.Inner inner = new Outer().new Inner();
        Outer.Inner inner = outer.new Inner();

        // 调用方法
        inner.Heart();

    }
}

4.3 匿名内部类【重点】

/*
    接口:
 */
public interface Animal {

    // 抽象方法
    void eat();

}
/*
    接口Animal的实现类
 */
public class Cat implements Animal {

    // 重写接口的抽象方法
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }

}
/*
    测试类!
 */
public class Test {
    public static void main(String[] args) {
        /*
            // 创建对象
            Animal animal = new Cat(); // 父接口类型的变量指向子类对象!

            // 调用方法
            animal.eat();
            
            // 实现类Cat存在的价值:重写父接口的方法并执行!【与这个实现类关系不大!】
        */
    }
}

实现类的类名无所谓!只要重写的父接口的方法就行!===>>>> 干脆就别定义类了,直接重写方法就行了!

/*
    测试类!
 */
public class Test {
    public static void main(String[] args) {  
      
        // 创建对象【子类就是父类!Cat就是Animal】
        Animal animal = new Animal(){

            // 方法只能写在类中,方法外!
            // 重写接口的抽象方法
            @Override
            public void eat() {
                System.out.println("猫吃鱼!");
            }

        }; // new的是Animal的一个子类(没有名字)!

        /*
            匿名内部类!(在Test类的内部,然后没有名字!) 必定是Animal接口的一个子类(没有名字!)
            {
                // 方法只能写在类中,方法外!
                // 重写接口的抽象方法
                @Override
                public void eat() {
                    System.out.println("猫吃鱼!");
                }
            }
         */

        animal.eat();
    }
}

匿名内部类的作用:简化代码(不用定义类)!

nterface Animal {

// 抽象方法
void eat();

}


```java
/*
    接口Animal的实现类
 */
public class Cat implements Animal {

    // 重写接口的抽象方法
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }

}
/*
    测试类!
 */
public class Test {
    public static void main(String[] args) {
        /*
            // 创建对象
            Animal animal = new Cat(); // 父接口类型的变量指向子类对象!

            // 调用方法
            animal.eat();
            
            // 实现类Cat存在的价值:重写父接口的方法并执行!【与这个实现类关系不大!】
        */
    }
}

实现类的类名无所谓!只要重写的父接口的方法就行!===>>>> 干脆就别定义类了,直接重写方法就行了!

/*
    测试类!
 */
public class Test {
    public static void main(String[] args) {  
      
        // 创建对象【子类就是父类!Cat就是Animal】
        Animal animal = new Animal(){

            // 方法只能写在类中,方法外!
            // 重写接口的抽象方法
            @Override
            public void eat() {
                System.out.println("猫吃鱼!");
            }

        }; // new的是Animal的一个子类(没有名字)!

        /*
            匿名内部类!(在Test类的内部,然后没有名字!) 必定是Animal接口的一个子类(没有名字!)
            {
                // 方法只能写在类中,方法外!
                // 重写接口的抽象方法
                @Override
                public void eat() {
                    System.out.println("猫吃鱼!");
                }
            }
         */

        animal.eat();
    }
}

匿名内部类的作用:简化代码(不用定义类)!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值