Java复习03

3 篇文章 0 订阅
继承
  1. 继承概述

    继承的格式

    • 格式:pulic class 子类名 extends 父类名()
    • 范例:public class Zi extends Fu()
    • Fu: 是父类,也被称为基类、超类
    • Zi:是子类,也被称为派生类

    继承中子类的特点:

    • 子类可以有父类的内容
    • 子类还可以有自己特有的内容
  2. 继承的好处和弊端

    1. 继承的好处
      • 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
      • 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
    2. 继承的弊端
      • 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了独立性
    3. 什么时候使用继承?
      • 继承体现的关系: is a
      • 假设法:我有两个类A和B,如果他们满足A时B的一种,就说明他们存在继承关系,这个时候就可以考虑使用继承来体现,否则就不能滥用继承
      • 举例:苹果和水果,猫和动物,猫和狗
  3. 继承中变量的访问特点

    在子类方法中访问一个变量

    • 子类局部范围找
    • 子类成员范围找
    • 父类成员范围找
    • 如果都没有就报错(不考虑父亲的父亲)
  4. super

    super关键字的用法和this关键字的用法相似

    • this:代表本类对象的引用(this关键字指向调用该方法的对象,一般我们是在当前类中使用this关键字,所以我们常说this代表本类对象的引用)

    • super:代表父类存储空间的标识(可以理解为父类对象引用)

      关键字访问成员变量访问构造方法访问成员方法
      thisthis.成员变量
      访问本类成员变量
      this(…)
      访问本类构造方法
      this.成员方法(…)
      访问本类成员方法
      supersuper.成员变量
      访问父类成员变量
      super(…)
      访问父类构造方法
      super.成员方法(…)
      访问父类成员方法
    1. 继承中构造方法的访问特点

      子类中所有的构造方法默认都会访问父类中无参的构造方法

      • 因为子类会继承父类中的数据,可能还会使用父类的数据。所有,子类初始化之前,一定要先完成父类数据初始化
      • 每一个子类构造方法的第一条语句默认都是super()

      如果父类中没有无参构造方法,只有带参构造方法,该怎么办?

      • 通过使用super关键字去显示的调用父类的带参构造方法

      • 在父类中自己提供一个无参构造方法

        推荐:自己给出无参构造方法

    2. 继承中成员方法的访问特点

      通过子类对象访问一个方法

      • 子列成员范围内找
      • 父类成员范围内找
      • 如果都没有就报错(不考虑父亲的父亲)
    3. super内存图

      main方法加载到栈内存,接着指向main方法中的语句Zi Z 加载到main方法中,new Zi() 堆内存出现由new申请的地址,并进行子类数据的初始化,调用Zi的构造方法加载到栈内存,在Zi的构造方法中第一行访问默认的无参构造方法,其中第一行为super(),访问Fu的内容,Fu的内容进行初始化在堆内存中由super空间存储Fu类初始化的数据,再访问Fu类构造方法,Fu类构造方法加载到栈内存,在控制台输出Fu类无参构造方法被调用,Fu类无参都在方法指向完毕从栈内存消失,访问Fu类无参构造方法结束后回到栈内存访问zi类无参构造方法,结束后Zi类无参构造方法从栈内存消失,再调用Zi.show()方法,show()方法被加载到栈内存并访问执行,执行完毕后在栈内存中消失。再往下看method()方法,zi类中并无method()方法但Fu类中有,故调用Fu类method()方法。最后main方法执行完毕,从栈内存中消失。

    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

    1. 方法重写

      方法重写概述

      • 子类中出现了和父类中一模一样的方法声明

      方法重写的应用

      • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,既沿袭了父类的功能,又定义了子类特有的内容。

      @override

      • 是一个注解
      • 可以帮助我们检查重写方法的方法声明的正确性
    2. 方法重写的注意事项

      • 私有方法不能被重写(父类私有成员子类是不能继承的)
      • 子类方法访问权限不能更低(public>默认>私有)
    3. Java中继承的注意事项

      • Java中类只支持单继承,不支持多继承
      • Java中类支持多层继承
修饰符
    1. 包的概述和使用

      其实就是文件夹

      作用:对类进行分类管理

      包的定义格式:

      • 格式:package 包名;(多级包用.分开)
      • 范例:package com.itheima;

      带包的Java类编译和执行

      • 手动创建包:

        新建文件夹com,在其中再建一个包heima,把编译生成(javac)的文件放到其中,完成。

      • 自动创建包:

        javac -d . HelloWorld.java

      运行时带包运行 java com.itheima.HelloWorld

  1. 导包

    1. 导包的概述和使用

      使用不同包下的类时,使用的时候要写全类的全路径,写起来太麻烦了

      为了简化带包的操作,Java就提供了导包的功能

      导包的格式

      • 格式:import包名;
      • 范例:import cn.itcast.Teacher
  2. 修饰符

    1. 修饰符的分类

      • 权限修饰符

        修饰符同一个类中同一个包中子类无关类不同包的子类不同包的无关类
        private
        默认
        protected
        public
      • 状态修饰符

        • final

          final关键字时最终的意思,可以修饰成员方法、成员变量、类

          final修饰的特点

          • 修饰方法:表明该方法是最终方法,不能被重写
          • 修饰变量:表明该变量是常量,不能被再次赋值
          • 修饰类:表明该类是最终类,不能被继承

          final修饰局部变量

          • 变量是基本类型:final修饰指的是基本类型的数据值不能发生改变
          • 变量是引用类型:final修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的
        • static

          static关键字是静态的意思,可以修饰成员方法、成员变量

          static修饰的特点

          • 被类的所有对象共享

            这也是我们判断使用使用静态关键字的条件

          • 可以通过类名调用

            当然也可以通过对象名调用

             private String name;
                private int age;
                public static String university;
            
            		Students.university="PKU";
                    Students s1=new Students();
                    s1.name="ling";
                    s1.age=20;
                    s1.show();
                    Students s2=new Students();
                    s2.name="feng";
                    s2.age=20;
                    s2.show();
            

          static访问特点

          • 静态成员方法只能访问静态成员
多态
  1. 多态概述

    同一个对象,在不同时刻表现出来不同形态

    举例:猫

    我们可以说猫是猫:猫 cat =new 猫();

    也可以说猫是动物:动物 animal=new 猫();

    这里猫在不同的时刻表现出来了不同的形态,这就是多态

    多态的前提和体现

    • 有继承/实现关系
    • 有方法重写
    • 有父类引用指向子类对象
  2. 多态中成员访问特点

    • 成员变量:编译看左边,执行看左边
    • 成员方法:编译看左边,执行看右边

    为什么成员变量和成员方法的访问不一样呢?

    • 因为成员方法有重写,而成员变量没有
  3. 多态的好处和弊端

    • 多态的好处:提高了程序的扩展性

      具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型与操作

    • 多态的弊端:不能使用子类特有的功能

      package heima06;
      
      public class Animal {
          public void eat() {
              System.out.println("动物吃东西");
          }
      }
      
      
      package heima06;
      
      public class Cat extends Animal {
          @Override
          public void eat() {
              System.out.println("猫吃鱼");
          }
      }
      
      
      package heima06;
      
      public class Pig extends Animal {
          @Override
          public void eat() {
              System.out.println("猪吃白菜");
          }
      }
      
      
      package heima06;
      
      public class Dog extends Animal {
          @Override
          public void eat() {
              System.out.println("狗吃骨头");
          }
      
          public void lookdoor() {
              System.out.println("狗看门");
          }
      }
      
      
      package heima06;
      
      public class AnimalOperator {
      
          /* public void useAnimal(Cat c){
               c.eat();
           }
           public void useAnimal(Dog d){
               d.eat();
           }*/
          public void useAnimal(Animal a) {
              a.eat();
      //       a.lookdoor();//报错
          }
      }
      
      
      package heima06;
      
      public class AnimalDemo {
          public static void main(String[] args) {
              AnimalOperator ao = new AnimalOperator();
              Cat c = new Cat();
              ao.useAnimal(c);
      
              Dog d = new Dog();
              ao.useAnimal(d);
      
              Pig p = new Pig();
              ao.useAnimal(p);
          }
      }
      
      
  4. 多态中的转型

    • 向上转型

      从子到父

      父类引用指向子类对象

    • 向下转型

      从父到子

      父类引用转为子类对象

      package heima07;
      
      public class Animal {
          public void eat() {
              System.out.println("动物吃东西");
          }
      }
      
      
      package heima07;
      
      public class Cat extends Animal {
          @Override
          public void eat() {
              System.out.println("猫吃鱼");
          }
      
          public void playGame() {
              System.out.println("猫捉迷藏");
          }
      }
      
      
      package heima07;
      
      public class AnimalDemo {
          public static void main(String[] args) {
              Animal a = new Cat(); //向上转型
              a.eat();
      //        a.playGame();//报错 Animal中没有playGame方法
      
              /*//创建Cat类对象
              Cat c =new Cat();
              c.eat();
              c.playGame();*/
      
              //向下转型
              Cat c = (Cat) a;
              c.eat();
              c.playGame();
              //解决了多态不能使用子类特有功能的弊端
          }
      }
      
      
  5. 多态转型内存图解

抽象类
  1. 抽象类概述

    在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类

  2. 抽象类的特点

    • 抽象类和抽象方法必须使用abstract关键字修饰

      • public abstract class 类名 {}
      • public abstract void eat();
    • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

    • 抽象类不能实例化

      抽象类如何实例化?参照多态的方式,通过子类对象实例化,这叫抽象类多态

    • 抽象类的子类

      要么重写抽象类中的所有抽象方法

      要么是抽象类

      package heima08;
      
      /*
          抽象类
       */
      public abstract class Animal {
          /*public void eat(){
              System.out.println("吃东西");
          }*/
          //抽象方法
          public abstract void eat();
      
          public void sleep() {
              System.out.println("睡觉");
          }
      }
      
      
      package heima08;
      
      public class Cat extends Animal {
          @Override
          public void eat() {
              System.out.println("猫吃鱼");
          }
      }
      
      
      package heima08;
      
      public abstract class Dog extends Animal {
      
      }
      
      
      package heima08;
      
      public class AnimalDemo {
          public static void main(String[] args) {
              /*Animal a=new Animal();
              a.eat();*/
      
              Animal a = new Cat();
              a.eat();
              a.sleep();
          }
      }
      
      
  3. 抽象类的成员特点

    • 成员变量

      ​ 可以是变量

      ​ 也可以是常量

    • 构造方法

      ​ 有构造方法,但是不能实例化

      ​ 用于子类访问父类数据的初始化

    • 成员方法

      ​ 可以有抽象方法:限定子类必须完成某些动作

      ​ 也可以有非抽象方法:提高代码复用性

      案例:猫和狗

      package heima09;
      
      public abstract class Animal {
          private String name;
          private int age;
      
          public Animal() {
          }
      
          public Animal(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          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 abstract void eat();
      }
      
      
      package heima09;
      
      public class Cat extends Animal {
          public Cat() {
          }
      
          public Cat(String name, int age) {
              super(name, age);
          }
      
          @Override
          public void eat() {
              System.out.println("猫吃鱼");
          }
      }
      
      
      package heima09;
      
      //测试类
      public class AnimalDemo {
          public static void main(String[] args) {
              //创建对象,按照多态的方式
              Animal a = new Cat();
              a.setName("coffe");
              a.setAge(4);
              System.out.println(a.getName() + "," + a.getAge());
              a.eat();
              System.out.println("--------------");
      
              a = new Cat("coffe", 5);
              System.out.println(a.getName() + "," + a.getAge());
              a.eat();
          }
      }
      
      
接口
  1. 接口概述

    接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用

    Java的接口更多的体现在对行为的抽象

  2. 接口的特点

    • 接口用关键字interface修饰

      ​ public interface 接口名{}

    • 类实现接口用implements表示

      ​ public class 类名 implements 接口名{}

    • 接口不能实例化

      ​ 接口参照多态的方式,通过实现类对象实例化,这叫接口多态

      ​ 多态的形式:具体类多态、抽象类多态、接口多态

      ​ 多态的前提:有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现)类对象

    • 接口的实现类

      ​ 要么重写接口中的所有抽象方法

      ​ 要么是抽象类

      package heima10;
      
      public class Cat implements Jumpping {
          @Override
          public void jump() {
              System.out.println("猫可以跳高了");
          }
      }
      
      
      package heima10;
      
      public abstract class Dog implements Jumpping {
      }
      
      
      package heima10;
      
      public interface Jumpping {
          public abstract void jump();
      }
      
      
      package heima10;
      
      public class JumppingDemo {
          public static void main(String[] args) {
              Jumpping j = new Cat();
              j.jump();
          }
      }
      
      
  3. 接口的成员特点

    • 成员变量

      ​ 只能是常量

      ​ 默认修饰符:public static final

    • 构造方法

      ​ 接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在

      ​ 一个类如果没有父类,默认继承Object类

    • 成员方法

      ​ 只能是抽象方法

      ​ 默认修饰符:public abstract

      ​ 关于接口中的方法,JDK8和JDK9中有一些新特性,后面再讲解

      案例:猫和狗

      ​ 对猫和狗进行训练,他们就可以跳高了,这里加入了跳高功能。请采用抽象类和接口来实现猫狗案 例。

      package heima12;
      
      public interface Jumpping {
          public abstract void jump();
      }
      
      
      package heima12;
      
      public abstract class Animal {
          private String name;
          private int age;
      
          public Animal() {
          }
      
          public Animal(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          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 abstract void eat();
      }
      
      
      package heima12;
      
      public class Cat extends Animal implements Jumpping {
          public Cat() {
          }
      
          public Cat(String name, int age) {
              super(name, age);
          }
      
          @Override
          public void eat() {
              System.out.println("猫吃鱼");
          }
      
          @Override
          public void jump() {
              System.out.println("猫可以跳高了");
          }
      }
      
      
      package heima12;
      
      public class AnimalDemo {
          public static void main(String[] args) {
              Jumpping j = new Cat();
              j.jump();
              System.out.println("-----------------------");
      
              Animal a = new Cat();
              a.setName("coffe");
              a.setAge(4);
              System.out.println(a.getName() + "," + a.getAge());
              a.eat();
      //        a.jump();
      
              a = new Cat("coffe", 5);
              System.out.println(a.getName() + "," + a.getAge());
              a.eat();
              System.out.println("-----------------------");
      
              Cat c = new Cat();
              c.setName("coffe");
              c.setAge(3);
              System.out.println(c.getName() + "," + c.getAge());
              c.eat();
              c.jump();
          }
      }
      
      
  4. 子类和接口的关系

    • 类和类的关系

      ​ 继承关系,只能单继承,但是可以多层继承

    • 类和接口的关系

      ​ 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

    • 接口和接口的关系

      ​ 继承关系,可以单继承,也可以多继承

  5. 抽象类和接口的区别

    • 成员区别

      抽象类 变量,常量:有构造方法;有抽象方法,也有非抽象方法

      接口 常量;抽象方法

    • 关系区别

      类与类 继承,单继承

      类与接口 实现,可以单实现,也可以多实现

      接口与接口 继承,单继承,多继承

    • 设计理念区别

      抽象类 对类抽象,包括属性、行为

      接口 对行为抽象,主要是行为

      抽象类是对事物的抽象,而接口是对行为的抽象

  6. 案例:运动员和教练

    需求:我们现在有乒乓球运动员和篮球运动员,乒乓球教练和篮球教练。为了出国交流,跟乒乓球相关的人员都需要学习英语。请用所学只是分析,这个案例中有哪些具体类,哪些抽象类,哪些接口,并用代码实现。

    分析:从具体到抽象

    ​ 乒乓球运动员

    ​ 乒乓球教练 在这里插入图片描述

    ​ 篮球教练

    实现:从抽象到具体

    使用:使用的是具体的类的对象

    思路:

    1. 定义说英语接口 成员方法:说英语();
    2. 定义抽象人类 成员变量:姓名,年龄;构造方法:无参,带参;成员方法:get/set方法,吃饭();
    3. 定义抽象教练类,继承人类 构造方法:无参,带参;成员方法:教();
    4. 定义抽象运动员类,继承人类 构造方法:无参,带参;成员方法:学();
    5. 定义具体篮球教练类,继承教练类 构造方法:无参,带参;成员方法:重写吃饭(){…},重写教(){…}
    6. 定义具体乒乓球教练,继承教练类,实现说英语接口 构造方法:无参,带参;成员方法:重写吃饭(){…},重写教(){…},重写说英语(){…}
    7. 定义具体篮球运动员类,继承运动员类 构造方法:无参,带参;成员方法:重写吃饭(){…},重写学习(){…}
    8. 定义具体乒乓球运动员类,继承运动员类,实现说英语接口 构造方法:无参,带参;成员方法:重写吃饭(){…},重写学习(){…},重写说英语(){…}
    9. 定义测试类,写代码测试
package heima13;

public interface SpeakEnglish {
    public abstract void speak();
}

package heima13;

public abstract class Person {
    private String name;
    private int age;

    public Person(){
    }

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

    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 abstract void eat();
}

package heima13;

public abstract class Player extends Person {
    public Player() {
    }

    public Player(String name, int age) {
        super(name, age);
    }

    public abstract void studey();
}

package heima13;

public abstract class Coach extends Person {
    public Coach() {
    }

    public Coach(String name, int age) {
        super(name, age);
    }

    public abstract void teach();
}

package heima13;

public class BasketballCoach extends Coach {
    public BasketballCoach() {
    }

    public BasketballCoach(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("篮球教练教如何运球和投篮");
    }

    @Override
    public void eat() {
        System.out.println("篮球教练吃羊肉,喝羊奶");
    }
}

package heima13;

public class PingPangCoach extends Coach implements SpeakEnglish {
    public PingPangCoach() {
    }

    public PingPangCoach(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("乒乓球教练教如何发球喝接球");
    }

    @Override
    public void eat() {
        System.out.println("乒乓球教练吃小白菜,喝大米粥");
    }

    @Override
    public void speak() {
        System.out.println("乒乓球教练说英语");
    }
}

package heima13;

public class BasketballPlayer extends Player {
    public BasketballPlayer() {
    }

    public BasketballPlayer(String name, int age) {
        super(name, age);
    }

    @Override
    public void studey() {
        System.out.println("篮球运动员学习如何运球喝投篮");
    }

    @Override
    public void eat() {
        System.out.println("篮球运动员吃牛肉,喝牛奶");
    }
}

package heima13;

public class PingPangPlayer extends Player implements SpeakEnglish {
    public PingPangPlayer() {
    }

    public PingPangPlayer(String name, int age) {
        super(name, age);
    }

    @Override
    public void studey() {
        System.out.println("乒乓球运动员学习如何发球和接球");
    }

    @Override
    public void eat() {
        System.out.println("乒乓球运动员吃大白菜,和小米粥");
    }

    @Override
    public void speak() {
        System.out.println("乒乓球运动员说英语");
    }
}

package heima13;

public class PersonDemo {
    public static void main(String[] args) {
        PingPangPlayer ppp = new PingPangPlayer();
        ppp.setName("wh");
        ppp.setAge(30);
        System.out.println(ppp.getName() + "," + ppp.getAge());
        ppp.eat();
        ppp.studey();
        ppp.speak();
        System.out.println("--------------------------");

        BasketballPlayer bp = new BasketballPlayer();
        bp.setName("ym");
        bp.setAge(30);
        System.out.println(bp.getName() + "," + bp.getAge());
        bp.studey();
        bp.eat();

    }
}

行参和返回值
  1. 形参和返回值

    1. 类名作为形参和返回值

      package heima14;
      
      public class Cat {
          public void eat() {
              System.out.println("猫吃鱼");
          }
      }
      
      
      package heima14;
      
      public class CatOperator {
          public void useCat(Cat c) {
              c.eat();
          }
      }
      
      
      package heima14;
      
      public class CatDemo {
          public static void main(String[] args) {
              //创建操作类对象,并调用方法
              CatOperator co = new CatOperator();
              Cat c = new Cat();
              co.useCat(c);
          }
      }
      
      
      • 方法的形参是类名,其实需要的是该类的对象
      • 方法的返回值是类名,其实返回的是该类的对象
    2. 抽象类名作为形参和返回值

      package heima15;
      
      public abstract class Animal {
          public abstract void eat();
      }
      
      
      package heima15;
      
      public class AnimalOperator {
          public void useAnimal(Animal a) {//Animal a=new Cat();
              a.eat();
          }
      }
      
      
      package heima15;
      
      public class Cat extends Animal {
          @Override
          public void eat() {
              System.out.println("猫吃鱼");
          }
      }
      
      
      package heima15;
      
      public class AnimalDemo {
          public static void main(String[] args) {
              AnimalOperator ao = new AnimalOperator();
              Animal a = new Cat();
              ao.useAnimal(a);
          }
      }
      
      
      • 方法的形参是抽象类名,其实需要的是该抽象类的子类对象
      • 方法的返回值是抽象类名,其实返回的是该抽象类的子类对象
    3. 接口名作为形参和返回

      package heima16;
      
      public interface Jumpping {
          void jump();
      }
      
      
      package heima16;
      
      public class JumppingOperator {
          public void useJumpping(Jumpping j) {//Jumpping j=new Cat();
              j.jump();
          }
      
          public Jumpping getJumpping() {
              Jumpping j = new Cat();
              return j;
          }
      
      }
      
      
      package heima16;
      
      public class Cat implements Jumpping {
          @Override
          public void jump() {
              System.out.println("猫可以跳高");
          }
      }
      
      
      package heima16;
      
      public class JumppingDemo {
          public static void main(String[] args) {
              JumppingOperator jo = new JumppingOperator();
              Jumpping j = new Cat();
              jo.useJumpping(j);
      
              Jumpping j2 = jo.getJumpping();//new Cat()
              j2.jump();
          }
      }
      
      
      • 方法的形参是接口名,其实需要的是该接口的实现类对象
      • 方法的返回值是接口名,其实返回的是该接口的实现类对象
内部类
  1. 内部类概述

    内部类:就是在一个类中定义一个类。举例:在一个类A的内部定义一个类B,类B就被称为内部类

    内部类的定义格式

    • 格式

      public class 类名{

      ​ 修饰符class 类名{

      ​ }

      ​ }

    • 范例:

      public class Outer{

      ​ public class Inner{

      ​ }

      ​ }

      内部类的访问特点

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

      • 外部类要访问内部类的成员,必须创建对象

        package heima17;
        
        public class Outer {
            private int num = 10;
        
            public class Inner {
                public void show() {
                    System.out.println(num);//内不类可以直接访问外部类对象
                }
            }
        
            public void method() {
        //        show();//外部类不可以直接访问内部类方法
                Inner i = new Inner();
                i.show();//需要创建内部类对象调用他们的方法
            }
        }
        
        
  2. 成员内部类

    按照内部类在类中定义的位置不同,可以分为如下两种形式

    • 在类的成员位置:成员内部类

    • 在类的局部位置:局部内部类

      成员内部类,外界如何创建对象使用?

      • 格式:外部类名.内部类名 对象名 =外部类对象.内部类对象;

      • 范例:Outer.Inner oi=new Outer().new Inner();

        package heima17;
        
        public class InnerDemo {
            public static void main(String[] args) {
                //创建内部类对象,并调用方法
        //        Inner i =new Inner();//不能直接创建内部类
                Outer.Inner oi = new Outer().new Inner();
                oi.show();
        
            }
        }
        
        

        但一般这样用:

        package heima17;
        
        import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
        
        public class Outer {
            private int num = 10;
        
           /* public class Inner {
                public void show() {
                    System.out.println(num);//内不类可以直接访问外部类对象
                }
            }*/
        
            private class Inner {
                public void show() {
                    System.out.println(num);
                }
        
            }
        
            public void method() {
                Inner i = new Inner();
                i.show();
            }
        }
        
        
        package heima17;
        
        public class InnerDemo {
            public static void main(String[] args) {
                //创建内部类对象,并调用方法
        //        Inner i =new Inner();//不能直接创建内部类
                Outer o = new Outer();
                o.method();
        
            }
        }
        
        
  3. 局部内部类

    局部内部类是在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象并使用

    该类可以直接访问外部类的成员,也可以访问方法内的局部变量

    package heima17;
    
    import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
    
    public class Outer {
        private int num = 10;
    
        public void method() {
            int num2=20;
            class Inner {    //局部内部类外部是无法直接访问的,也要通过外部类调用method方法间接访问
                public void show() {
                    System.out.println(num);
                    System.out.println(num2);
                }
            }
            Inner i = new Inner();
            i.show();
        }
    }
    
    
    package heima17;
    
    public class InnerDemo {
        public static void main(String[] args) {
            Outer o = new Outer();
            o.method();
        }
    }
    
    
  4. 匿名内部类

    前提:存在一个类或接口,这里的类可以是具体类也可以是抽象类

    • 格式

      new 类名或接口名(){

      ​ 重写方法;

      };

    • 范例:

      new Inter(){

      ​ public void show(){
      ​ }

      }

      本质:是一个继承了该类或者实现了该接口的子类匿名对象

      package heima17;
      
      public interface Inter {
          void show();
      }
      
      
      package heima17;
      
      import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
      
      public class Outer {
      
          public void method() {
              /*new Inter(){
                  @Override
                  public void show() {
                      System.out.println("匿名内部类");
                  }
              };*/ //这样它只是一个方法,并没有被调用使用
              new Inter() {
                  @Override
                  public void show() {
                      System.out.println("匿名内部类");
                  }
              }.show();//这样才调用了内部的show方法
              //如果是多次调用
              Inter i = new Inter() {
                  @Override
                  public void show() {
                      System.out.println("匿名内部类");
                  }
              };
              i.show();
          }
      }
      
      
      package heima17;
      
      public class InnerDemo {
          public static void main(String[] args) {
              Outer o = new Outer();
              o.method();
          }
      }
      
      
  5. 匿名内部类在开发中的使用

    package heima18;
    
    public class JumppingDemo {
        public static void main(String[] args) {
            //需求:创建接口操作的对象,调用method方法
            JumppingOperator jo = new JumppingOperator();
            Jumpping j = new Cat();
            jo.method(j);
    
            Jumpping j2 = new Dog();
            jo.method(j2);
            System.out.println("-----------------------");
            //用匿名内部类实现
            jo.method(new Jumpping() {
                @Override
                public void jump() {
                    System.out.println("猫可以跳高了");
                }
            });
    
            jo.method(new Jumpping() {
                @Override
                public void jump() {
                    System.out.println("狗可以跳高了");
                }
            });
            //采用后面的匿名内部类的形式就不需要另外创建两个类
        }
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值