Java核心编程总结(三、多态与内部类)

本文总结了Java核心编程中的关键知识点,包括多态的概念、形式及应用、不同类型间的自动和强制类型转换,以及内部类(静态、实例、局部和匿名)的深入解析。同时介绍了包的概念以及权限修饰符在不同范围内的作用。
摘要由CSDN通过智能技术生成

0.写在前面

  1. 本笔记用作复习查看用,基础完整总结部分,基础不牢,地动山摇!
🔥Java帝国之行🔥地址
Java核心编程总结(一、继承) 🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209463
Java核心编程总结(二、抽象类与接口)🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209487
Java核心编程总结(三、多态与内部类)🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209507
Java核心编程总结(四、异常与线程) 🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209529
Java核心编程总结(五、线程池与死锁)🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209580
Java核心编程总结(六、常用API与集合)🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209607
Java核心编程总结(七、Stream流)🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209624
Java核心编程总结(八、IO输入输出流)🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209648
Java核心编程总结(九、File文件类)🔥https://blog.csdn.net/Augenstern_QXL/article/details/116209674
Java核心编程总结(十、反射) 🔥https://blog.csdn.net/Augenstern_QXL/article/details/117744497

1.基础回顾+面试

1.0多态

概念:同一个类型的对象,执行同一个行为,在不同状态下会表现出不同的行为特征

理解:都是动物类型的对象,执行run方法,在不同状态下表现出不同行为特征

1.1多态形式

  • 父类类型 对象名称 = new 子类构造器
  • Anilam c = new Cat()
  • 接口 对象名称 = new 实现类构造器
  • 父类类型范围 > 子类类型范围
public class PolymorphicDemo {
    public static void main(String[] args) {
        //父类类型 对象名称 = new 子类构造器;
        Animal dlam = new Cat();
        dlam.run(); //对于方法的调用: 编译(写代码)看左边Animal,运行看右边 Cat
                    //看左边指的是看等号的左边,等号左边是Animal,会找Animal里面的run方法,不报错
                    //运行的时候看等号的右边,等号右边是Cat,执行Cat里面的run方法
        // 🐱跑的飞快~~~
        System.out.println(dlam.name); //对于变量的调用: 编译看左边,运行看左边
        //动物名称Animal


        Animal taiDi = new Dog();
        taiDi.run(); //对于方法的调用: 编译(写代码)看左边,运行看右边
        //🐕跑的飞快~~~
        System.out.println(taiDi.name); //对于变量的调用: 编译看左边,运行看左边
        //动物名称Animal
    }
}

class Dog extends Animal{
    public String name = "狗的名称Dog";
    @Override
    public void  run(){
        System.out.println("🐕跑的飞快~~~");
    }
}

class Cat extends Animal{
    public String name = "猫的名称Cat";
    @Override
    public void run(){
        System.out.println("🐱跑的飞快~~~");
    }
}


class Animal{
    public String name = "动物名称Animal";
    public void run(){
        System.out.println("动物跑的飞快~~~");
    }
}

1.2多态的识别技巧

  • 对于方法的调用:编译(写代码)看左边,运行看右边
  • 对于变量的调用:编译看左边,运行看左边

1.3多态的使用前提

  1. 必须存在继承或者实现关系
  2. 必须存在父类类型的变量引用(指向)子类类型的对象
  3. 需要存在方法重写

1.4多态的优劣势

  1. 优势
    • 在多态形式下,右边对象可以实现组件化切换,业务功能也随之改变,便于扩展和维护。可以实现类与类之间的解耦
    • 实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,可以传入一切子类对象进行方法的调用,更能体现出多态的扩展性与便利
  2. 劣势
    • 多态形式下,不能直接调用子类特有的功能。(编译看左边!!)
    • 因为父类中没有子类独有的功能,所以代码在编译阶段就直接报错了

1.5引用类型自动类型转换

我们先来看基本数据类型的转换

  1. 小范围类型的变量或者值可以直接赋值给大范围类型的变量
  2. 大范围类型的变量或者值必须强制类型转换给小范围类型的变量

引用数据类型转换的思想是一样的

  1. 父类类型的范围 > 子类类型的范围
  2. Animal > Cat
  3. 子类类型的对象或者变量可以自动类型转换赋值给父类类型的变量
Animal a = new Cat();

1.6引用类型的强制类型转换

  • 父类类型的变量或者对象必须强制类型转换成子类类型的变量,否则报错!

  • 强制类型转换的格式:

    • 类型 变量名称 = (类型)(对象或者变量)

    • Animal a = new Wolf();
      // 把动物类型的变量a转换为真实的狼类型
      Wolf w = (Wolf) a;
      

1.7多态下类型转换异常问题研究

  • 有继承/实现关系的两个类型就可以进行强制类型转换,编译阶段一定不报错
  • 但是在运行阶段可能出现:类型转换异常 ClassCastException
  • 建议在进行强制类型转换之前先判断变量的真实类型,再强制类型转换(instanceof)
Animal a1 = new Cat();
// Wolf w1 = (Wolf) a1; //编译阶段没有报错 在运行阶段可能出现类型转换异常
if(a1 instanceof Cat){
    // 如果a1 属于猫类型,执行抓老鼠
    Cat c1 = (Cat) a1;
    c1.catchMouse();
}else if(a1 instanceof Wolf){
    // 如果a1 属于狼类型,执行抓羊
    Wolf w1 =(Wolf) a1;
    w1.catchSheep();
}

1.8内部类

  1. 什么是内部类?

    答:定义在一个类里面的类就是内部类

  2. 内部类有什么用?

    答:可以提供更好的封装性,内部类有更多的权限修饰符,封装性有了更多的控制

  3. 内部类的分类

    • 静态内部类
    • 实例内部类(成员内部类)
    • 局部内部类
    • 匿名内部类(重点)

1.8.1静态内部类(了解)

  1. 什么是静态内部类?

    答:有static修饰,属于外部类本身,会加载一次

  2. 静态内部类的成分

    答:

    • 类中有的成分它都有,静态内部类属于外部类本身,只会加载一次

    • 所以它的特点与外部类是完全一样的,只是位置在别人里面而已

  3. 静态内部类的访问格式

    答:外部类名称.内部类名称

  4. 静态内部类创建对象的格式

    答:外部类名称.内部类名称 对象名称 = new 外部类名称.内部类构造器

  5. 静态内部类中是否可以直接访问外部类的静态成员?

    答:可以的,外部类的静态成员只有一份,可以被共享

  6. 静态内部类中是否可以直接访问外部类的实例成员?

    答:不可以,外部类的实例成员必须用外部类对象访问

请仔细理解下方代码,理解语法即可,静态内部类几乎不用!!!

public class InnerClass {
    public static void main(String[] args) {
        //外部类名称.内部类名称 对象名称 = new 外部类名称.内部类构造器
        Outter.Inner in = new Outter.Inner();
        in.setName("张三");
        in.setAge(12);
        in.show();

    }

}
class Outter{
    private double salary;
    public static int age1 = 15;
    // 静态内部类: 有static修饰,属于外部类本身,只会加载一次
    public static class Inner{
        private String name;
        private int age;

        public Inner() {
        }

        public Inner(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 void show() {
            System.out.println(name +"是" + age + "岁");
            System.out.println(age1);
            // 15
            // System.out.println(salary); 报错
        }
    }
}

1.8.2实例内部类(了解)

  1. 什么是实例内部类?

    答:无static修饰的内部类,属于外部类的每个对象,跟着对象一起加载

  2. 实例内部类中的成分

    答:实例内部类中不能定义静态成员,其他的都可以定义,可以定义常量

  3. 实例内部类的访问格式

    答:外部类名称.内部类名称

  4. 实例内部类创建对象的格式

    答:外部类名称.内部类名称 对象名称 = new 外部类构造器.new 内部类构造器

  5. 实例内部类中是否可以直接访问外部类的静态成员?

    答:可以的,外部类的静态成员可以被共享访问

  6. 实例内部类中是否可以访问外部类的实例成员?

    答:可以的,实例内部类属于外部类对象,可以直接访问当前外部类的实例成员

public class InnerClass {
    public static void main(String[] args) {
        // 实例内部类属于外部类对象。实例内部类的宿主是外部类对象!
        Outter.Inner in = new Outter().new Inner();
        in.show();
    }
}

class Outter{
    public static int age = 11;
    private String salary;
    // 实例内部类: 无static 修饰,属于外部类的对象
    public class Inner{
        private String name;
        // 不能在实例内部类中定义静态成员!!
        // public static String schoolName; 报错

        // 可以定义常量
        public static final String schoolName = "黑马";

        public String getName() {
            return name;
        }

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



        // 实例方法
        public void show(){
            System.out.println(age);
            System.out.println(salary);
        }
    }
}

1.8.3局部内部类(了解)

  1. 什么是局部内部类?

    答:在方法,构造器,代码块,for循环中定义的内部类,就是局部内部类

  2. 局部内部类的成分

    答:只能定义实例成员,不能定义静态成员,可以定义常量

  3. 局部内部类基本没啥用

public class InnerClass {
    static {
        // 局部内部类
        abstract class A{

        }
    }
    public static void main(String[] args) {
        // 局部内部类
        class A{


        }
    }
    public static void test(){
        // 局部内部类
        class Animal{

        }
        // 局部内部类
        class A extends Animal{

        }
    }
}

1.8.4匿名内部类(重点)

  1. 什么是匿名内部类?

    答:就是一个没有名字的局部内部类

  2. 匿名内部类的作用

    答:匿名内部类可以简化代码,是开发中常用的形式

  3. 匿名内部类的格式

    new 类名|抽象类|接口(形参){
        方法重写
    }
    
  4. 匿名内部类的特点

    答:1.匿名内部类是一个没有名字的内部类

    ​ 2.匿名内部类一旦写出来,就会立即创建一个匿名内部类的对象返回

    ​ 3.匿名内部类的对象的类型相当于是当前 new 的那个类型的子类类型

public class Anonymity {
    public static void main(String[] args) {
        Animal a = new Animal() {
            @Override
            public void run() {
                System.out.println("🐱跑的贼溜~~~");
            }
        };
        a.run();
        a.go();

    }
}
abstract class Animal{
    public abstract void run();

    public void go(){
        System.out.println("开始go~~~");
    }
}

1.9包

  • 相同包下的类可以直接访问
  • 不同包下的类必须导包,才可以使用
  • 导包格式: import 包名.类名

1.10权限修饰符

private缺省protectedpublic
本类中
本包下的其他类中×
其他包下的类中×××
其他包下的子类中××
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生命是有光的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值