Java SE-多态及内部类

多态概述
多态成员方法的使用
多态成员变量的使用
多态好处
成员内部类
静态内部类
局部内部类
匿名内部类

多态

多态概述
  • 继承或是实现是多态的前提
  • 多态是指对象的多态性(仔细体会)
  • 代码中体现多态:父类引用指向子类对象
  • 多态:通过父类引用不同的子类
  • Java实现多态的三个必要条件
  • 继承、重写、向上转型
多态中方法的使用
  • 使用规则:new 谁 则调用谁的方法,没有则向上找
  • 成员方法:编译看左边,运行看右边
class Animal {
    //父类方法
    public void bark() {
        System.out.println("动物叫!");
    }
}

class Dog extends Animal {

    //子类重写父类的bark方法
    public void bark() {
        System.out.println("汪、汪、汪!");
    }
    //子类自己的方法
    public void dogType() {
        System.out.println("这是什么品种的狗?");
    }
}


public class Test {

    public static void main(String[] args) {
        Animal a = new Animal();
        Animal b = new Dog();
        Dog d = new Dog();

        a.bark();   //动物叫!
        b.bark();   //汪、汪、汪!
        //b.dogType(); 
        //b.dogType()编译不通过
        d.bark();    //汪、汪、汪!
        d.dogType();    //这是什么品种的狗?
    }

}
  • 注意:这里b是父类的引用,指向子类的对象,因此不能获取子类的方法(dogType()方法),当调用back()方法时,因为子类覆盖了父类的back()方法,因此会调用子类的back()方法
  • 因此,向上转型在运行时会遗忘子类对象与父类不同名的方法,也会覆盖与父类中相同的方法(方法名,参数列表都相同)
多态中成员变量的使用
  • 只有方法可以重写,成员变量不可以重写
  • 直接通过对象名称访问成员变量,看等号左面是谁,优先使用谁,没有则想上找
  • 间接通过成员方法访问成员变量,看方法属于谁,优先用谁,没有则想上找
public class Fu {
    int num = 10;

    public void shouNum() {
        System.out.println(num);
    }
}

public class Zi extends Fu{
    int num = 5;

    @Override
    public void shouNum() {
        System.out.println(num);
    }
}

/**
 *   多态成员变量的使用
 *       只有方法可以重写,成员便令不可以重写
 *       1、直接通过对象名称访问成员变量,看等号左面是谁,优先使用谁,没有则想上找
 *       2、间接通过成员方法访问成员变量,看方法属于谁,优先用谁,没有则想上找
 * */
public class MutiField {
    public static void main(String[] args) {
        Fu obj = new Zi();

        System.out.println(obj.num);  //10
        obj.shouNum();  //5
    }
}
使用多态好处
  • 无论等号右面new哪个子类对象,等号左面的调用方法都不会改变

在这里插入图片描述

多态总结:
  • 在调用变量是,看等号左面是谁,则优先使用谁,没有则向上找
  • 在调用方法时,看new 谁则优先使用谁,没有则想上找
  • 调用变量时,编译时看左边,运行时也看左边
  • 调用方法时,编译时看左边,运行时看右边
成员内部类
  • 内部类提供了更好的封装,可以把内部类隐藏在外部类之外,不允许同一个包中的其他类访问该类
  • 内部类方法可以直接访问外部类的所有数据,包括私有数据
  • 内部类所有实现功能使用外部类同样实现
  • 内部类运训继承多个非接口类型
  • 内部类在外部类中相当于一个成员变量
  • 内部类里可以直接访问外部类的属性和方法反之不行
  • 必须使用外部类对象来创建内部类对象
  • 内部类 对象名 = 外部类对象.new 内部类();
  • 内部类不能由static变量和方法,因为成员内部类需要在创建外部类之后才能创建它
  • 内部类和外部类成员变量和方法重名时,内部类默认访问自己的,外部类使用this访问
// People.java
//外部类People
public class People {
    private String name = "LiLei";         //外部类的私有属性
    //内部类Student
    public class Student {
        String ID = "20151234";               //内部类的成员属性
        //内部类的方法
        public void stuInfo(){
            System.out.println("访问外部类中的name:" + name);
            System.out.println("访问内部类中的ID:" + ID);
        }
    }

    //测试成员内部类
    public static void main(String[] args) {
        People a = new People();     //创建外部类对象,对象名为a
        Student b = a.new Student(); //使用外部类对象创建内部类对象,对象名为b
        // 或者为 People.Student b = a.new Student();
        b.stuInfo();   //调用内部对象的suInfo方法
    }
}
静态内部类
  • 静态内部类不能直接访问外部类的非静态成员,可以通过new 外部类().成员 的方法访问
  • 如果外部类的静态成员与内部类的成员名称相同,可通过 类名.静态成员 访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过 成员名 直接调用外部类的静态成员。
  • 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();
// People.java
//外部类People
public class People {
    private String name = "LiLei";         //外部类的私有属性

/*外部类的静态变量。
Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。
*/
    static String ID = "510xxx199X0724XXXX";

    //静态内部类Student
    public static class Student {
        String ID = "20151234";               //内部类的成员属性
        //内部类的方法
        public void stuInfo(){
            System.out.println("访问外部类中的name:" + (new People().name));
            System.out.println("访问外部类中的ID:" + People.ID);
            System.out.println("访问内部类中的ID:" + ID);
        }
    }

    //测试成员内部类
    public static void main(String[] args) {
        Student b = new Student();   //直接创建内部类对象,对象名为b
        b.stuInfo();                 //调用内部对象的suInfo方法
    }
}
局部内部类
  • 局部内部类,是指内部类定义在方法和作用域内
// People.java
//外部类People
public class People {
    //定义在外部类中的方法内:
    public void peopleInfo() {
        final String sex = "man";  //外部类方法中的常量
        class Student {
            String ID = "20151234"; //内部类中的常量
            public void print() {
                System.out.println("访问外部类的方法中的常量sex:" + sex);
                System.out.println("访问内部类中的变量ID:" + ID);
            }
        }
        Student a = new Student();  //创建方法内部类的对象
        a.print();//调用内部类的方法
    }
    //定义在外部类中的作用域内
    public void peopleInfo2(boolean b) {
        if(b){
            final String sex = "man";  //外部类方法中的常量
            class Student {
                String ID = "20151234"; //内部类中的常量
                public void print() {
                    System.out.println("访问外部类的方法中的常量sex:" + sex);
                    System.out.println("访问内部类中的变量ID:" + ID);
                }
            }
            Student a = new Student();  //创建方法内部类的对象
            a.print();//调用内部类的方法
        }
    }
    //测试方法内部类
    public static void main(String[] args) {
        People b = new People(); //创建外部类的对象
        System.out.println("定义在方法内:===========");
        b.peopleInfo();  //调用外部类的方法
        System.out.println("定义在作用域内:===========");
        b.peopleInfo2(true);
    }
}
匿名内部类
  • 匿名内部类,顾名思义,就是没有名字的内部类。正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口
// Outer.java
public class Outer {

    public Inner getInner(final String name, String city) {
        return new Inner() {
            private String nameStr = name;
            public String getName() {
                return nameStr;
            }
        };
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        Inner inner = outer.getInner("Inner", "NewYork");
        System.out.println(inner.getName());
    }
}
interface Inner {
    String getName();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值