static、接口、多态、内部类相关复习内容

没脑子 程序猿

时间: 2021-05-02 阅读: 129 字数:32702

{}
接口是Java语言中的一种引用类型,是方法的"集合",所以接口的内部主要就是定义方法,包含常量,抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(jdk9)。

目录

第一章 接口

知识点--3.1 概述

目标:

  • 引用数据类型除了类其实还有接口,接下来学习接口的概述

路径:

  • 接口的概述

讲解:

概述: 接口是Java语言中的一种引用类型,是方法的"集合",所以接口的内部主要就是定义方法,包含常量,抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(jdk9)。

  • 抽象方法【重要】
  • 默认方法
  • 静态方法
  • 私有方法
  • 自定义常量

接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。

public class 类名.java-->.class

public interface 接口名.java-->.class

引用数据类型:数组,类,接口。

接口的使用,它不能创建对象,但是可以被实现(implements ,类似于被继承)。一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。

小结:

  • 接口是Java语言中的一种引用类型,
  • 接口中主要用来定义方法的:
    • jdk7及其以前: 常量,抽象方法
    • jdk8: 额外增加默认方法和静态方法
    • jdk9及其以上: 额外增加了私有方法
  • 定义接口使用interface关键字, 编译之后也会产生class文件
  • 接口不能创建对象, 需要实现接口(implements), 实现接口的类叫做实现类(接口的子类)
    • 实现类: 普通类 必须重写接口中的抽象方法
    • 实现类 ;抽象类 可以不用重写接口中的抽象方法

知识点--3.2 定义格式

目标:

  • 如何定义一个接口

路径:

  • 定义格式的格式

讲解:

格式

public interface 接口名称 {
    // 常量
    // 抽象方法
    // 默认方法
    // 静态方法
}

案例

public interface IA {
    // 常量 默认修饰符 public static final  这三个修饰符可以省略
    public static final int NUM1 = 10;
    int NUM2 = 20;

    // 抽象方法 默认修饰符 public abstract 这2个修饰符可以省略
    public abstract void method1();
    void method2();

    // 默认方法 默认修饰符 public default public修饰符可以省略,default不可以省略
    public default void method3(){
        System.out.println("默认方法 method3");
    }

    default void method4(){
        System.out.println("默认方法 method4");
    }

    // 静态方法: public static修饰  static修饰符不可以省略 public可以省略
    public static void method5(){
        System.out.println("静态方法 method5");
    }

     // 私有静态方法 使用private static修饰  不可以省略
     private static void method6(){
        System.out.println("私有静态方法 method6");
    }

    // 私有非静态方法 使用private修饰
    private  void method7(){
        System.out.println("私有静态方法 method7");
    }
}

public class Test {
    public static void main(String[] args) {
        /*
            接口的定义:
                public interface 接口名{
                     jdk7及其以前:  常量,抽象方法
                     jdk8: 额外增加默认方法和静态方法
                     jdk9及其以上: 额外增加了私有方法
                }
         */
        System.out.println(IA.NUM1);// 10
    }

    // 类中的默认方法,使用默认权限修饰符(空)
    void method(){

    }
}

小结

知识点--3.3 实现接口

目标

  • 掌握什么是实现,以及如何实现接口

路径

  • 实现概述
  • 实现格式

讲解

实现概述

类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

实现格式

  • 类可以实现一个接口,也可以同时实现多个接口。
    • 类实现接口后,必须重写接口中所有的抽象方法,否则该类必须是一个“抽象类”。
      public interface IA{
          public void show1();
      }
      public interface IB{
          public void show2();
      }
      public class Zi implements IA ,IB{
          public void show1(){
          }
          public void show2(){
          }
      }
      
  • 类可以在“继承一个类”的同时,实现一个、多个接口;
    public class Fu{}
    public interface IA{}
    public interface IB{}
    public class Zi extends Fu implements IA,IB{//一定要先继承,后实现
    }
    

小结

知识点--3.4接口中成员的访问特点

目标

  • 掌握接口中成员访问特点

路径

  • 接口中成员访问特点概述
  • 案例演示

讲解

接口中成员访问特点概述

  接口中成员的访问特点:
                接口中的常量: 主要是供接口直接使用
                接口中的抽象方法: 供实现类重写的
                接口中的默认方法: 供实现类继承的(实现类中可以直接调用,实现类对象也可以直接调用)
                接口中的静态方法: 只供接口直接调用,实现类继承不了
                接口中的私有方法: 只能在接口中直接调用,实现类继承不了

案例演示

接口

/**
 * @Author:pengzhilin
 * @Date: 2020/4/16 11:57
 */
public interface IA {
    //  接口中的常量: 主要是供接口直接使用
    public static final int NUM = 10;

    // 接口中的抽象方法: 供实现类重写的
    public abstract void method1();

    // 接口中的默认方法: 供实现类继承使用(实现类中可以直接调用,实现类对象也可以直接调用)
    public default void method2(){
        System.out.println("默认方法method2");
        method4();
        method5();
    }

    // 接口中的静态方法: 只供接口直接调用,实现类继承不了
    public static void method3(){
        System.out.println("静态方法method3");
        method5();
    }

    // 接口中的私有方法: 只能在接口中直接调用,实现类继承不了
    private void method4(){// 只能在接口的默认方法中调用
        // 方法体
        method5();
    }

    private static void method5(){//
        // 方法体
    }
}

实现类:

/**
 * @Author:pengzhilin
 * @Date: 2020/4/16 11:59
 */
public class ImpA implements IA{

   /* @Override
    public void method2() {

    }*/

    @Override
    public void method1() {
        System.out.println("重写接口中的method1抽象方法");
    }
}


测试类:

/**
 * @Author:pengzhilin
 * @Date: 2020/4/16 11:54
 */
public class Test {
    public static void main(String[] args) {
        /*
            接口中成员的访问特点:
                接口中的常量: 主要是供接口直接使用
                接口中的抽象方法: 供实现类重写的
                接口中的默认方法: 供实现类继承的(实现类中可以直接调用,实现类对象也可以直接调用)
                接口中的静态方法: 只供接口直接调用,实现类继承不了
                接口中的私有方法: 只能在接口中直接调用,实现类继承不了
         */
        System.out.println(IA.NUM);// 10

        // 创建实现类对象,访问NUM常量
        ImpA ia = new ImpA();
        System.out.println(ia.NUM);// 10

        // 调用method2方法
        ia.method2();

        // 通过接口名调用接口中的静态方法
        IA.method3();
        //ia.method3();// 编译报错,
    }
}

小结

知识点--3.5 多实现时的几种冲突情况

目标

  • 理解多实现时的几种冲突情况

路径

  • 公有静态常量的冲突
  • 公有抽象方法的冲突
  • 公有默认方法的冲突
  • 公有静态方法的冲突
  • 私有方法的冲突

讲解

公有静态常量的冲突

了解即可, 一般会使用静态所在类的类名去调用

  • 实现类不继承冲突的变量

    interface IA{

      public static final int a = 10;
      public static final int b= 20;
    

    } interface IB{

      public static final int a = 30;
    

    } class Zi implements IA,IB{

      //只继承了b,没有继承a,因为a冲突了
    

    }

    public class Demo {

      public static void main(String[] args) {
          Zi z = new Zi();
       //   System.out.println(z.a);//编译错误
          System.out.println(z.b);
      }
    

    }

公有抽象方法的冲突

  • 实现类只需要重写一个

    interface IA{

      public void show();
    

    } interface IB{

      public void show();
    

    } class Zi implements IA,IB{

      @Override
      public void show() {//子类只需要重写一个show()即可
          System.out.println("子类的show()...");
      }
    

    } public class Demo {

      public static void main(String[] args) {
          Zi z = new Zi();
          z.show();
      }
    

    }

公有默认方法的冲突

  • 实现类必须重写一次最终版本

    interface IA{

      public default void show(){
          System.out.println("IA");
      }
    

    } interface IB{

      public default void show(){
          System.out.println("IB");
      }
    

    } class Zi implements IA,IB{

      @Override
      public void show() {//必须重写一次的show()
          System.out.println("Zi的show()....");
      }
    

    } public class Demo {

      public static void main(String[] args) {
          Zi z = new Zi();
          z.show();
      }
    

    }

公有静态方法的冲突

  • 静态方法是直接属于接口的,不能被继承,所以不存在冲突
    interface IA{
        public static  void show(){
            System.out.println("IA");
        }
    }
    interface IB{
        public static void show(){
            System.out.println("IB");
        }
    }
    class Zi implements IA,IB{
    
    }
    public class Demo {
        public static void main(String[] args) {
            Zi z = new Zi();
            z.show();//编译错误,show()不能被继承。
        }
    }
    

私有方法的冲突

  • 私有方法只能在本接口中直接使用,不存在冲突

小结

  • 接口中的静态常量
    • 可以被子类继承, 可以子类的类名. 去调用, 子类对象也可以调用
    • 特殊情况: 两个接口同名的静态常量, 子类不能使用
  • 两个接口中的抽象方法同名
    • 子类只需要重写一次
  • 两个接口中的默认方法同名
    • 子类必须重写一次
  • 父类中的方法和接口中的默认方法同名
    • 使用父类中的方法
  • 接口中的静态方法同名
    • 没有冲突, 只能使用接口名.去调用
    • 子类不能使用
  • 接口中的私有方法
    • 没有冲突

知识点--3.6 接口和接口的关系

目标

  • 理解接口与接口之间的关系,以及接口继承时的冲突情况

路径

  • 接口与接口之间的关系
  • 接口继承时的冲突情况
    • 公有静态常量的冲突
    • 公有抽象方法的冲突
    • 公有默认方法的冲突
    • 公有静态方法和私有方法的冲突

讲解

接口与接口之间的关系

  • 接口可以“继承”自另一个“接口”,而且可以“多继承”。
    interface IA{}
    interface IB{}
    interface IC extends IA,IB{//是“继承”,而且可以“多继承”
    }
    

接口继承接口的冲突情况

公有静态常量的冲突

interface IA{
    public static final int a = 10;
    public static final int b = 30;
}
interface IB{
    public static final int a = 20;
}
interface IC extends IA,IB{//没有继承a
}
//测试:
main(){
    System.out.println(IC.a);//错误的
}

公有抽象方法冲突

interface IA{
    public void show();
}
interface IB{
    public void show();
}
interface IC extends IA,IB{//IC只继承了一个show()
}
class Zi implements IC{
    //重写一次show()
    public void show(){
    }
}

公有默认方法的冲突

interface IA{
    public default void d1(){
    }
}
interface IB{
    public default void d1(){
    }
}
interface IC extends IA,IB{//必须重写一次d1()
    public default  void d1(){
    }
}

公有静态方法和私有方法

  • 不冲突,因为静态方法是直接属于接口的,只能使用接口直接访问,而私有方法只能在接口中访问,也没有冲突

小结

实操--3.7 抽象类和接口的练习

需求:

通过实例进行分析和代码演示抽象类和接口的用法。

1、举例:

犬: 父类 ---->抽象类

    行为:吼叫;吃饭;  

缉毒犬: 继承犬类

    行为:吼叫;吃饭;缉毒;

public abstract class Dog{
    // 吼叫   抽象方法 
    // 吃饭   抽象方法 
}

public interface JiDu{
    // 缉毒 抽象方法
}

public class JiDuDog extends Dog implements JiDu{
    // 重写吼叫,吃饭方法
    // 实现缉毒的方法 ----  缉毒方式
}


缉毒猪,缉毒猫,缉毒候....
  • 如果一个父类中的某个方法,所有子类都有不同的实现,那么该方法就应该定义成抽象方法,所以该父类就是抽象类 (父类一般都是抽象类)
  • 如果某个功能是一个类额外增加的,那么就可以把这个额外的功能定义到接口中,再这个类去实现

分析:

由于犬分为很多种类,他们吼叫和吃饭的方式不一样,在描述的时候不能具体化,也就是吼叫和吃饭的行为不能明确。当描述行为时,行为的具体动作不能明确,这时,可以将这个行为写为抽象行为,那么这个类也就是抽象类。

可是有的犬还有其他额外功能,而这个功能并不在这个事物的体系中 , 例如 : 缉毒犬。缉毒的这个功能有好多种动物都有 , 例如 : 缉毒猪 , 缉毒鼠。我们可以将这个额外功能定义接口中 ,让缉毒犬继承犬且实现缉毒接口 , 这样缉毒犬既具备犬科自身特点也有缉毒功能。 
  • 额外的功能---> 在接口中定义,让实现类实现
  • 共性的功能---> 在父类中定义,让子类继承

实现:

//定义缉毒接口 缉毒的词组(anti-Narcotics)比较长,在此使用拼音替代
interface JiDu{
    //缉毒
    public abstract void jiDu();
}
//定义犬科,存放共性功能
abstract class Dog{
    //吃饭
    public abstract void eat();
    //吼叫
    public abstract void roar();
}
//缉毒犬属于犬科一种,让其继承犬科,获取的犬科的特性,
//由于缉毒犬具有缉毒功能,那么它只要实现缉毒接口即可,这样即保证缉毒犬具备犬科的特性,也拥有了缉毒的功能
class JiDuQuan extends Dog implements JiDu{
    public void jiDu() {
    }
    void eat() {
    }
    void roar() {
    }
}

//缉毒猪
class JiDuZhu implements JiDu{
    public void jiDu() {
    }
}

小结:

  • 额外的功能---> 在接口中定义,让实现类实现
    • 如果可以确定的通用功能,使用默认方法
    • 如果不能确定的功能,使用抽象方法
  • 共性的功能---> 在父类中定义,让子类继承
    • 如果可以确定的通用功能,使用默认方法
    • 如果不能确定的功能,使用抽象方法

第二章 多态

知识点-- 概述

目标:

  • 了解什么是多态,以及形成多态的条件

路径:

  • 引入
  • 概念
  • 形成多态的条件

讲解:

引入

多态是继封装、继承之后,面向对象的第三大特性。

生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。

定义

  • 多态: 是指同一行为,对于不同的对象具有多个不同表现形式。
  • 同一种事物的多种形态
  • 程序中多态: 是指同一方法,对于不同的对象具有不同的实现.

前提条件【重点】

  1. 继承或者实现【二选一】
  2. 父类引用指向子类对象【格式体现】
  3. 方法的重写【意义体现:不重写,无意义】

小结:

  • 多态: 是指同一行为,对于不同的对象具有多个不同表现形式。
  • 条件:
    • 继承或者实现
    • 父类引用指向子类的对象
    • 方法的重写

知识点-- 实现多态

目标:

  • 如何实现多态

路径:

  • 多态的实现

讲解:

多态的体现:父类的引用指向它的子类的对象:

父类类型 变量名 = new 子类对象;
变量名.方法名();

父类类型:指子类对象继承的父类类型,或者实现的父接口类型。

class Animal{}
class Cat extends Animal{}
class Dog extends Animal{}
clsss Person{}
//测试类:
main(){
    Animal a1 = new Cat();
    Animal a2 = new Dog();
    Animal a3 = new Person();//编译错误,没有继承关系。
}

小结:

  • 父类的引用指向子类的对象

知识点-- 多态时访问成员的特点

目标

  • 掌握多态时访问成员的特点

路径:

  • 多态时成员变量的访问特点
  • 多态时成员方法的访问特点

讲解:

  • 多态时成员变量的访问特点

    • 编译看左边,运行看左边
      • 简而言之:多态的情况下,访问的是父类的成员变量
  • 多态时成员方法的访问特点

    • 非静态方法:编译看左边,运行看右边
      • 简而言之:编译的时候去父类中查找方法,运行的时候去子类中查找方法来执行
    • 静态方法:编译看左边,运行看左边
      • 简而言之:编译的时候去父类中查找方法,运行的时候去父类中查找方法来执行
  • 注意:多态的情况下是无法访问子类独有的方法

  • 演示代码:

    public class Demo1 {

      public static void main(String[] args) {
          // 父类的引用指向子类的对象
          Animal anl1 = new Dog();
          // 访问非静态方法
          anl1.eat();
    
          // 访问成员变量num
          System.out.println(anl1.num);//10
    
          // 访问静态方法
          anl1.sleep();
    
          // 多态想要调用子类中独有的方法
          // anl1.lookHome(); 错误的,无法访问  多态的弊端:无法访问子类独有的方法
    
      }
    

    }

    public class Animal {

      int num = 10;
    
      public void eat(){
          System.out.println("吃东西...");
      }
    
      public static void sleep(){
          System.out.println("Animal类中的睡觉方法...");
      }
    

    }

    public class Dog extends Animal {

      int num = 20;
    
     // 重写
      public void eat() {
          System.out.println("狗吃骨头");
      }
    
      public static void sleep(){
          System.out.println("Dog类中的睡觉方法...");
      }
    
      public void lookHome(){
          System.out.println("狗正在看家...");
      }
    

    }

小结:

知识点-- 多态的几种表现形式

目标:

  • 多态的几种表现形式

路径:

  • 普通父类多态
  • 抽象父类多态
  • 父接口多态

讲解:

  • 多态的表现形式:
    • 普通父类多态
      public class Fu{}
      public class Zi extends Fu{}
      public class Demo{
          public static void main(String[] args){
              Fu f = new Zi();//左边是一个“父类”
          }
      }
      
    • 抽象父类多态
      public abstract class Fu{}
      public class Zi extends Fu{}
      public class Demo{
          public static void main(String[] args){
              Fu f = new Zi();//左边是一个“父类”
          }
      }
      
    • 父接口多态 public interface A{} public class AImp implements A{} public class Demo{
        public static void main(String[] args){
            A a = new AImp();
        }
      
      }

小结:

知识点-- 多态的应用场景:

目标:

  • 掌握多态在开发中的应用场景

路径:

  • 变量多态 -----> 意义不大
  • 形参多态----> 常用
  • 返回值多态---> 常用

讲解:

多态的几种应用场景:

定义一个Animal类,让Dog和Cat类继承Animal类:
public class Animal {
    public void eat(){
        System.out.println("吃东西...");
    }
}
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼...");
    }
}

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        /*
            多态的应用场景:
                1.变量多态
                2.形参多态
                3.返回值多态
         */
        // 1.变量多态
        Animal anl = new Dog();
        anl.eat();

        // 2.形参多态
        Dog dog = new Dog();
        invokeEat(dog);

        Cat cat = new Cat();
        invokeEat(cat);// 实参赋值给形参: Animal anl = new Cat();

        // 3.返回值多态
        Animal anl2 = getAnimal();// 返回值赋值给变量: Animal anl2 = new Dog()
    }

    //  3.返回值多态
    // 结论:如果方法的返回值类型为父类类型,那么就可以返回该父类对象以及其所有子类对象
    public static Animal getAnimal(){
//        return new Animal();
        return new Dog();
//        return new Cat();
    }

    // 形参多态: 当你调用invokeEat方法的时候,传入Animal类的子类对象
    // Animal anl = dog; ====>  Animal anl = new Dog();
    // 结论:如果方法的参数是父类类型,那么就可以接收所有该父类对象以及其所有子类对象
    // Object类:是java中所有类的父类,所以如果参数为Object类型,那么就可以传入一切类的对象
    public static void invokeEat(Animal anl){
        anl.eat();
    }

}

小结:

知识点-- 多态的好处和弊端

目标:

  • 实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利。但有好处也有弊端

步骤:

  • 多态的好处和弊端

讲解:

  • 好处

    • 提高了代码的扩展性
  • 弊端

    • 多态的情况下,只能调用父类的共性内容,不能调用子类的特有内容。
  • 示例代码

    // 父类 public abstract class Animal {

      public abstract void eat();  
    

    }
    // 子类 class Cat extends Animal {

      public void eat() {  
          System.out.println("吃鱼");  
      }  
      public void catchMouse(){
           System.out.println("猫抓老鼠");  
      }
    

    }
    class Dog extends Animal {

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

    }

定义测试类:

多态的好处:
public class Test {
    public static void main(String[] args) {
        // 创建对象
        Cat c = new Cat();  
        Dog d = new Dog(); 

        // 调用showCatEat 
        showCatEat(c);
        // 调用showDogEat 
        showDogEat(d); 

        /*
        以上两个方法, 均可以被showAnimalEat(Animal a)方法所替代
        而执行效果一致
        */
        showAnimalEat(c);
        showAnimalEat(d); 
    }

    public static void showCatEat (Cat c){
        c.eat(); 
    }

    public static void showDogEat (Dog d){
        d.eat();
    }

    public static void showAnimalEat (Animal a){
        a.eat();
    }
}

多态的弊端============
      public static void main(String[] args) {
        // 多态形式,创建对象
        Aniaml anl = new Cat();  
        anl.eat();
        anl.catchMouse();// 编译报错, 编译看父类(左边),父类中没有定义catchMouse方法
    }

小结:

知识点-- 引用类型转换

目标:

  • 向上转型与向下转型,instanceof关键字

步骤:

  • 向上转型
  • 向下转型
  • instanceof关键字

讲解:

向上转型

  • 子类类型向父类类型向上转换的过程,这个过程是默认的。
     Aniaml anl = new Cat();  
    

向下转型

  • 父类类型向子类类型向下转换的过程,这个过程是强制的。
     Aniaml anl = new Cat();  
     Cat c = (Cat)anl;//向下转型
     c.catchMouse();// 可以访问 子类独有的功能,解决多态的弊端
    

instanceof关键字

  • 向下强转有风险,最好在转换前做一个验证 :
  • 格式:
    变量名 instanceof 数据类型 
    如果变量属于该数据类型,返回true。
    如果变量不属于该数据类型,返回false。
    
    if( anl instanceof Cat){//判断anl是否能转换为Cat类型,如果可以返回:true,否则返回:false
        Cat c = (Cat)anl;//安全转换
    }
    

小结

第三章 内部类

知识点-- 内部类

目标:

  • 内部类的概述

步骤:

  • 什么是内部类
  • 成员内部类的格式
  • 成员内部类的访问特点

讲解:

什么是内部类

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。

成员内部类

  • 成员内部类 :定义在类中方法外的类。

定义格式:

class 外部类 {
    class 内部类{

    }
}

在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car 中包含发动机类Engine ,这时,Engine就可以使用内部类来描述,定义在成员位置。

代码举例:

class Car { //外部类
    class Engine { //内部类

    }
}

访问特点

  • 内部类可以直接访问外部类的成员,包括私有成员。
  • 外部类要访问内部类的成员,必须要建立内部类的对象。

创建内部类对象格式:

外部类名.内部类名 对象名 = new 外部类型().new 内部类型();

访问演示,代码如下:

public class Body {// 外部类

    // 成员变量
    private int numW = 10;

    int num = 100;

    // 成员方法
    public void methodW1(){
        System.out.println("外部类中的methodW1方法...");
    }

    public void methodW2(){
        System.out.println("外部类中的methodW2方法...");
        // 创建内部类对象
        Body.Heart bh = new Body().new Heart();
        // 访问内部类成员变量
        System.out.println("内部类成员变量numN:"+bh.numN);
        // 访问内部类成员方法
        bh.methodN2();
    }

    public class Heart{// 成员内部类
        // 成员变量
        int numN = 20;

        int num = 200;

        // 成员方法
        public void methodN(){
            System.out.println("内部类中的methodN方法...");
            // 访问外部类成员变量
            System.out.println("外部类成员变量:"+numW);
            // 访问外部类成员方法
            methodW1();
        }

        public void methodN2(){
            System.out.println("内部类中的methodN2方法...");
        }

        public void methodN3(){
            int num = 300;
            System.out.println("局部变量num:"+num);// 300
            System.out.println("内部类成员变量num:"+this.num);// 200
            System.out.println("外部类成员变量num:"+Body.this.num);// 100
        }
    }
}
public class Demo {
    public static void main(String[] args) {
        // 测试
        // 创建外部类对象,调用外部类的方法methodW2
        Body body = new Body();
        body.methodW2();

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

        // 创建内部类对象,调用内部类的methodN方法
        Body.Heart heart = new Body().new Heart();
        heart.methodN();

        System.out.println("=======================");
        heart.methodN3();// 300  200  100
    }
}

小结:

内部类:将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
成员内部类的格式:
    public class 外部类名{
         public class 内部类名{

        }
    }
成员内部类的访问特点:
    - 内部类可以直接访问外部类的成员,包括私有成员。
    - 外部类要访问内部类的成员,必须要建立内部类的对象。

成员内部类的创建方式:
    外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

知识点-- 匿名内部类

目标:

  • 匿名内部类

步骤:

  • 匿名内部类的概述
  • 匿名内部类的格式

讲解:

概述

  • 匿名内部类 :是内部类的简化写法。它的本质是一个带具体实现的 父类或者父接口的 匿名的 子类对象。

代码一

public abstract class Animal {
    public abstract void eat();
}
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            - 匿名内部类的概述:本质就是继承了父类或者实现了接口的匿名子类的对象
            - 匿名内部类的格式:
                new 类名\接口名(){
                    方法重写
                };

            - 匿名内部类的作用: 为了简化代码,并没有什么特殊的功能

            需求: 调用Aniaml类的eat()方法
            1.创建一个子类继承Animal类
            2.在子类中重写eat方法
            3.创建子类对象
            4.使用子类对象调用eat方法

            想要调用抽象类中的方法,必须具备以上4步,那能不能减后呢? 可以 使用匿名内部类
         */
        Animal anl1 = new Dog();
        anl1.eat();

        Animal anl2 = new Animal() {
            @Override
            public void eat() {
                System.out.println("Animal子类的eat方法...");
            }
        };
        anl2.eat();

    }
}

代码二

public interface AInterface {
    void method();
}
public class AImp implements AInterface {
    @Override
    public void method() {
        System.out.println("AImp 实现类重写method方法....");
    }
}
public class Demo {
    public static void main(String[] args) {
        /*
             匿名内部类:
                本质是一个继承了父类的匿名子类的对象
                本质是一个实现了接口的匿名实现类的对象

              案例: A接口中有一个抽象方法method(),现在需要调用A接口中的method方法
              思路:
                1.创建一个实现类实现A接口
                2.重写A接口中的抽象方法method()
                3.创建实现类对象
                4.使用实现类对象调用method方法

               想要调用A接口中的method方法,按照传统方式,必须有以上4步,一步都不可少
               前面三步就是为了得到A接口的实现类对象

            现在: 匿名内部类可以表示一个接口的匿名实现类对象,所以,可以直接创建接口的匿名内部类来调用method方法即可
         */
        AInterface a = new AInterface(){
            @Override
            public void method() {
                System.out.println("匿名内部类方式重写method方法....");
            }
        };
        a.method();

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

        AInterface a2 = new AImp();
        a2.method();

        System.out.println("======================");
        AInterface a3 = new AInterface() {
            @Override
            public void method() {
                // 实现
            }
        };
    }
}

小结

第四章 引用类型使用小结

目标

实际的开发中,引用类型的使用非常重要,也是非常普遍的。我们可以在理解基本类型的使用方式基础上,进一步去掌握引用类型的使用方式。基本类型可以作为成员变量、作为方法的参数、作为方法的返回值,那么当然引用类型也是可以的。在这我们使用两个例子 , 来学习一下。

路径

  • 类名作为方法参数和返回值
    • 类名作为方法的参数: 调用方法传入的是该类的对象
    • 类名作为方法的返回值: 方法返回的是该类的对象
  • 抽象类作为方法参数和返回值
    • 抽象类作为方法的参数, 调用方法传入的是该类的子类对象
    • 抽象类作为方法的返回值: 方法返回的是该类的子类对象
  • 接口作为方法参数和返回值
  • 类作为成员变量
  • 抽象类作为成员变量 不常见
  • 接口作为成员变量 不常见

讲解

6.1 类名作为方法参数和返回值

public class Person{
  public void eat(){
    System.out.println("吃饭");
  }
}
public class Test{
  public static void main(String[] args){
        method(new Person());
           Person p = createPerson();
  }
    
  //引用类型作为方法参数,在前面笔记本案例中我们也使用了接口类型作为方法参数
  pubic static void method(Person p){
       p.eat();
  }
    
  //引用类型作为返回值
  public static Person createPerson(){
        return new Person();
  }
}

6.2 抽象类作为方法参数和返回值

  • 抽象类作为形参:表示可以接收任何此抽象类的"子类对象"作为实参;

  • 抽象类作为返回值:表示"此方法可以返回此抽象类的任何子类对象";

    /* 定义一个抽象类 */ public abstract class Person{

      public void eat(){
          System.out.println("吃饭");
      }
      public abstract void work();
    

    } /定义子类Student/ public class Student extends Person{

      public void work(){
          System.out.println("学生的工作是学习...");
      }
    

    } /测试类/ public class Test{

       public static void main(String[] args) {
          //调用方法
          //当抽象类作为参数时,实际传入的是抽象类的子类对象
          method(new Student());
      }
    
      public static void method(Person p){
      }
    
      //用抽象类作为方法返回值类型
      public static Person method2(){
          
          //当抽象类作为返回值类型时,实际返回的是抽象类的子类对象
          return new Student();
      }
      
    

    }

6.3 接口作为方法参数和返回值

  • 接口作为方法的形参:【同抽象类】

  • 接口作为方法的返回值:【同抽象类】

    /定义一个接口/ public interface USB{

      public void run();
    

    } /定义子类/ public class Keyboard implements USB{

      public void run(){
          System.out.println("使用键盘...");
      }
    

    } public class Mouse implements USB{

      public void run(){
          System.out.println("使用鼠标...");
      }
    

    } /定义测试类/ public class Test{

      public static void main(String[] args){
          //1.调用method1()方法,需要传入USB的任何子类对象都可以
          method1(new Keyboard());
          method2(new Mouse());
          
          //2.调用method2()方法,此方法可能返回一个Keyboard对象,也可能返回一个Mouse对象
          USB usb = method2();
          usb.run();
      }
      //接口作为形参
      public static void method1(USB usb){
          usb.run();
      }
      //接口作为返回值
      public static USB method2(){
    //      return new Keyboard();//OK的
          return new Mouse();//OK的    
      }
    

    }

6.4 类名作为成员变量

我们每个人(Person)都有一个身份证(IDCard) , 为了表示这种关系 , 就需要在Person中定义一个IDCard的成员变量。定义Person类时,代码如下:

class Person {
    String name;//姓名
    int age;//年龄
}

使用String 类型表示姓名 , int 类型表示年龄。其实,String本身就是引用类型,我们往往忽略了它是引用类型。如果我们继续丰富这个类的定义,给Person 增加身份证号 , 身份证签发机关等属性,我们将如何编写呢?这时候就需要编写一个IDCard类了

定义IDCard(身份证)类,添加身份证号 , 签发地等属性:

class IDCard {
    String idNum;//身份证号
    String authority;//签发地
  
      //getter和setter方法
      //...
      
      //toString方法
      //...
}

修改Person类:

public class Person {
    String name;//姓名
    int age;//年龄

    IDCard idCard;//表示自己的身份证信息

    //name和age的getter、setter方法
    //...

    public IDCard getIdCard() {
        return idCard;
    }

    public void setIdCard(IDCard idCard) {
        this.idCard = idCard;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", idCard=" + idCard +
                '}';
    }
}

测试类:

public class TestDemo {
    public static void main(String[] args) {
        //创建IDCard对象
        IDCard idCard = new IDCard();
        //设置身份证号
        idCard.setIdNum("110113201606066666");
        //设置签发地
        idCard.setAuthority("深圳市宝安区公安局");

        //创建Person对象
        Person p = new Person();
        //设置姓名
        p.setName("小顺子");
        //设置年龄
        p.setAge(2);
        //设置身份证信息
        p.setIdCard(idCard);

        //打印小顺子的信息
        System.out.println(p);
    }
}
输出结果:
Person{name='小顺子', age=2, idCard=IDCard{idNum='110113201606066666', authority='深圳市宝安区公安局'}}

类作为成员变量时,对它进行赋值的操作,实际上,是赋给它该类的一个对象。同理 , 接口也是如此 , 例如我们笔记本案例中使用usb设备。在此我们只是通过小例子 , 让大家熟识下引用类型的用法 , 后续在咱们的就业班学习中 , 这种方式会使用的很多。

6.5 抽象类作为成员变量

  • 抽象类作为成员变量——为此成员变量赋值时,可以是任何它的子类对象

    /定义抽象类/ public abstract class Animal{

      public abstract void sleep();
    

    } /定义子类/ public class Cat extends Animal{

      public void sleep(){
          System.out.println("小猫睡觉...");
      }
      public String toString(){
          return "一只可爱的小猫";
      }
    

    }

    /定义Student类/ public class Student{

      private String name;
      private int age;
      private Animal animal;//表示学生有一个动物,可以是Cat,也可以是Dog
      
      public Student(String name,int age,Animal animal){
          this.name = name;
          this.age = age;
          this.animal = animal;
      }
      public void setName(String name){
          this.name = name;
      }
      public String getName(){
          return this.name;
      }
      public void setAge(int age){
          this.age = age;
      }
      public int getAge(){
          return this.age;
      }
      public void setAnimal(Animal animal){
          this.animal = animal;
      }
      public Animal getAnimal(){
          return this.animal;
      }
      
      public String toString(){
          return "Student [name = " + name + 
                  " , age = " + age + 
                  " , animal = " + animal + 
                  "]";
      }
    

    } /定义测试类/ public class Test{

      public static void main(String[] args){
          Student stu = new Student();
          stu.setName("章子怡");
          stu.setAge(19);
          stu.setAnimal(new Cat());//表示Student有一只猫
          
          System.out.println(stu);//隐式调用stu.toString(),而stu.toString()中会隐式调用animal的toString().
      }
      
    

    }

6.6 接口作为成员变量

  • 接口类型作为成员变量——【同抽象类】

    /定义接口/ public interface Animal{

      public abstract void sleep();
    

    } /定义子类/ public class Cat implements Animal{

      public void sleep(){
          System.out.println("小猫睡觉...");
      }
      public String toString(){
          return "一只可爱的小猫";
      }
    

    }

    /定义Student类/ public class Student{

      private String name;
      private int age;
      private Animal animal;//表示学生有一个动物,可以是Cat,也可以是Dog
      
      public Student(String name,int age,Animal animal){
          this.name = name;
          this.age = age;
          this.animal = animal;
      }
      public void setName(String name){
          this.name = name;
      }
      public String getName(){
          return this.name;
      }
      public void setAge(int age){
          this.age = age;
      }
      public int getAge(){
          return this.age;
      }
      public void setAnimal(Animal animal){
          this.animal = animal;
      }
      public Animal getAnimal(){
          return this.animal;
      }
      
      public String toString(){
          return "Student [name = " + name + 
                  " , age = " + age + 
                  " , animal = " + animal + 
                  "]";
      }
    

    } /定义测试类/ public class Test{

      public static void main(String[] args){
          Student stu = new Student();
          stu.setName("章子怡");
          stu.setAge(19);
          stu.setAnimal(new Cat());//表示Student有一只猫  
          System.out.println(stu);//隐式调用stu.toString(),而stu.toString()中会隐式调用animal的toString().
      }
      
    

    }

小结

总结

  • 接口
    • 定义接口的格式
    • 实现接口的格式
    • 接口中成员的特点
    • 抽象类和接口的练习
  • 多态
    • 多态的前提
    • 多态情况下成员的访问特点
      • 成员变量: 编译看左边, 运行也看左边
      • 成员方法: 编译看左边, 运行看右边
    • 多态的使用场景和好处
      • 方法的形参定义成父类, 调用方法的时候可以传入所有子类的对象
    • 多态的弊端
    • 向上转型和向下转型
    • instanceof
  • 内部类
    • 成员内部类【了解】
    • 匿名内部类
      • 前提
      • 格式
      • 本质
    • 实际应用场景 : 参数的传递
本文章网址:https://www.sjxi.cn/detil/fcc202c3e1304d37b92d6fbd2fe28d97

打赏作者

本站为非盈利网站,如果您喜欢这篇文章,欢迎支持我们继续运营!

最新评论
当前未登陆哦
登陆后才可评论哦

湘ICP备2021009447号

×

(穷逼博主)在线接单

QQ: 1164453243

邮箱: abcdsjx@126.com

前端项目代做
前后端分离
Python 爬虫脚本
Java 后台开发
各种脚本编写
服务器搭建
个人博客搭建
Web 应用开发
Chrome 插件编写
Bug 修复