欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java 多态和内部类的使用方法

程序员文章站 2022-05-04 08:49:52
Java 多态和内部类1. 多态1.1 概述1.2 使用格式2. 内部类2.1 概述2.2 成员内部类2.3 匿名内部类(重点内容)1. 多态1.1 概述 多态是继封装、继承之后,面向对象的第三大特征。 在生活中,例如跑的动作,不同的动物跑起来也是不一样的;再比如飞的动作,鸟类、昆虫等都是不一样的。由此可见,同一种行为,不同的动物可以体现出不同的形式。多态就是这样一种状态。 多态:是指同一种行为,不同的表现形式。一般应用于继承和实现。1.2 使用格式多态的使用格式:父类变量 变量名 = n...

1. 多态

1.1 概述

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

 在生活中,例如跑的动作,不同的动物跑起来也是不一样的;再比如飞的动作,鸟类、昆虫等都是不一样的。由此可见,同一种行为,不同的动物可以体现出不同的形式。多态就是这样一种状态。

多态:是指同一种行为,不同的表现形式。一般应用于继承和实现。

1.2 使用格式

多态的使用格式:

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

	Fu fu = new Zi();

	接口 变量名 = new 实现类对象();
	变量名.方法名();

技巧:
 编译器看 = 左边类型, 运行时JVM 看 = 右边类型

   左边类型决定了变量 能调用哪些方法,
   右边类型决定了最终使用的方法是哪个 - 优先调用自己重写过的

  口诀: 编译看左边, 运行看右边

1.3 多态的基础代码演示

public class Fu {

    int age =10;
    int num = 100;
    int score = 1000;

    public void m1 (){
        System.out.println("Fu m1");
    }

    public void m2 (){
        System.out.println("Fu m2");
    }

    public int getAge() {
        return age;
    }
}
public class Zi extends Fu {
    int age = 20;
    int num = 999;
    int score =9999;

    @Override
    public void m1() {
        System.out.println("Zi m1");
    }

    public void m3 (){
        System.out.println("Zi m3");
    }

    public int getAge() {
        return age;
    }
}
/**
 * 多态的表现方面:成员变量的调用,字符类中拥有相同的成员
 *      并且都有一对 get/set方法
 *
 * 如果通过引用直接调用成员变量的时候 -f.age 看左边类型
 * 通过方法调用成员变量的时候 - f.getAge 看右边对象
 */
public class Main1 {
    public static void main(String[] args) {
        Fu f = new Zi();
        System.out.println(f.age);

        System.out.println(f.getAge());
    }
}
/**
 * 多态的表现方面,成员方法的调用
 * 最终调用的是哪个方法,优先调用子类重写过的,
 *      子类中如果没有重写,那就调用父类的方法
 */
public class Main2 {
    public static void main(String[] args) {
        Fu f = new Zi();
        System.out.println(f.age);
        System.out.println(f.num);
        System.out.println(f.score);
        f.m1();
        f.m2();
        System.out.println(f.getAge());

        System.out.println();

        Zi zi = (Zi) f;
        System.out.println(zi.age);
        System.out.println(zi.num);
        System.out.println(zi.score);

        zi.m1();
        zi.m2();
        zi.m3();
    }
}

1.4 向上转型

向上转型:多态本身是子类类型向上转换的过程,这个过程是默认的。

当父类引用指向一个子类对象时,便是向上转型。

	Animal c= new Cat();

	c.eat();

1.5 向下转型

向下转型:父类类型想子类类型向下转换的过程,这个过程是强制的。

 一个已经向下转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型

	Cat cat = (Cat) c;
        
	 cat.catchMouse();

1.6 转型异常

为了避免出现ClassCastException类型转换异常,可以使用instanceof 加粗样式 关键字,在转换之前先将引用变量和类型做效验,防止出现不符合类型转换的定义。

//编译器看c是Animal类型,和Dog是父子关系
        //Dog dog = (Dog) c;
        //运行时,发现c实际上Cat,不能转换为Dog 。解决方法,instanceof判断是不是存在 避免出现异常
        //ClassCastException 类型转换异常!

        if(d instanceof Dog){
            Dog dog = (Dog) d;
            dog.watchHouse();
        }

2. 内部类

2.1 概述

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

 种类: 成员内部类,静态内部类,局部内部类[匿名内部类]

使用方法:
      内部类中, 可以随意使用外部类成员
      
      外部类中, 使用内部类成员时需要创建内部类对象
      
      无关类中, 使用内部类成员
        1.间接调用, 在外部类方法中调用内部类方法
          main方法中, 调用外部类方法
        2.直接调用, 需要创建内部类对象
          外部类.内部类 a = new 外部类().new 内部类();
          
    内部类和外部类有同名成员变量
      外部类的成员变量: 外部类.this.变量
      内部类的成员变量: this.变量

2.2 成员内部类

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

访问特点:

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

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

代码举例:

public class Body {

    private int a =100;
    public void walk(){
        System.out.println("身体在行走!");
        //外部类,直接创建内部类对象
        Heart heart = new Heart();
        heart.beat();
        System.out.println(heart.num);
    }
    
    //成员内部类
    public class Heart{
        int num =100;
        int a = 99;

        public void beat(){
            System.out.println("心脏跳动!"+a);
            //调用内部类的a
            System.out.println(this.a);
            //调用外部类的a
            System.out.println(Body.this.a);
        }
    }
}


public class Main {
    public static void main(String[] args) {
        Body body = new Body();
        //间接调用内部类
        body.walk();

        //直接调用内部类,通过外部类对象创建内部类对象
        Body.Heart heart = body.new Heart();
        heart.beat();
    }
}

 注:内部类仍然是一个独立的类,在编译之后内部类会编译成独立的.class文件,但是前面会冠以外部类的类名和$符号。

例如:Person$Heart.class

2.3 匿名内部类(重点内容)

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

 在开发中,最常用到的内部类就是匿名内部类了。

 以接口举例,当你使用一个接口时,需要做以下几个步骤:

  1.定义子类
  2.重写接口中的方法
  3.创建子类对象
  4.调用重写后的方法

 匿名内部类的作用就是将这几个步骤进行简化。

前提
匿名内部类必须继承一个父类或者实现一个父接口。

代码部分:

public interface InterfaceA {
    void methodA();

    void methodB();
}


public class Main {
    public static void main(String[] args) {

        /**
         * 匿名内部类的本质:实现接口或者继承抽象类
         *
         * new InterfaceA(){....}
         * new:创建InterfaceA的实现类对象
         * InterfaceA:想要实现的接口名字或抽象类
         * {....}:真正的类,没有名字
         * 弊端:只能使用一次,只能创建一次对象
         */
        InterfaceA impl = new InterfaceA() {

            @Override
            public void methodA() {
                System.out.println("方法A");
            }

            @Override
            public void methodB() {
                System.out.println("方法B");
            }
        };

        impl.methodA();
        impl.methodB();
    }
}

输出结果:
Java 多态和内部类的使用方法

2.4 静态内部类

public class Outer {

    // 成员方法
    public void m1() {
        new Inner();
        new InnerField();
    }
    // 静态方法
    public static void m2() {
        new Inner();
//        new InnerField();
    }
    // 成员内部类
    public class InnerField {

    }
    // 外部类的成员变量
    int a = 10;
    // 外部类的静态成员变量
    static int b = 20;
    // 静态内部类, 属于类的
    public static class Inner {
        public void m3() {
            // 不能使用非静态成员
//            System.out.println(a);
            System.out.println(b);
        }
    }
}
public class Main {
    public static void main(String[] args) {
        // 成员内部类创建对象, 需要外部类对象
        Outer.InnerField inner1 = new Outer().new InnerField();

        // 静态内部类创建对象
        Outer.Inner inner2 = new Outer.Inner();

        // 简化 -> 需要import
        Inner inner3 = new Outer.Inner();
    }
}

本文地址:https://blog.csdn.net/weixin_44191224/article/details/107360691