3---多态+代码块+内部类+权限修饰符+Object类+Objects类

本文详细讲解了Java中的多态概念、内部类的应用、代码块的类型以及访问修饰符的作用。多态提高了代码的扩展性,但限制了对子类特有方法的调用。内部类分为成员内部类和局部内部类,其中静态内部类和匿名内部类有特定的使用场景。代码块包括静态代码块和实例代码块,分别在类加载和构造方法执行前运行。访问修饰符如public、private、protected和default决定了类和成员的可见范围。此外,还介绍了Object类的基本方法和Objects工具类的用途。
摘要由CSDN通过智能技术生成

1、多态

1概念:

​ 同一个事物,行为,具有多个不同的表现形式

2多态的格式

1.父类 变量名 = new 子类();
2.接口 变量名 = new 实现类();

3多态的前提

​ 有继承关系 或者 要有方法重写

4多态的“调用方法原理”

​ 【编译看左边,运行看右边】

​ 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后方法。如果子类没有重写该方法,就会调用父类的该方法。

5多态的好处

​ 【提高代码的扩展性】

​ 左边写父类,右边写子类,
​ 方法的参数写父类,调用方法时可以传入各种子类对象,可以避免写很多重载的方法,提高代码的扩展性

6多态的弊端

​ 只能调用父类有的方法,而不能调用子类特有的方法(功能)。

​ 解决办法:引用类型转换之向下转型

7引用类型转换: 子类和父类之间的转换

​ 1.【向上转型】:将子类转成父类,就是多态
父类 变量名 = new 子类();

​ 2.向下转型:将父类转成子类
子类 变量名 = (子类)父类变量;

8用于解决类型转换的异常情况:ClassCastException

​ 为了避免该异常,提供instancof关键字

​ 1、使用格式:变量 instanceof 类名; //返回值是一个布尔类型

​ 2、作用:判断变量是否是执行的类型,如果返回ture,表示变量是指定的类型

​ 3、使用场景:向下转型前做类型判断

2、内部类

概念:一个写到了另一个类的里面的类称为内部类。(类中类)

应用场景:一个事物内部还有一个事物,内部的事物脱离外部的事物无法独立运行

内部类的分类

​ 按照内部类在外部类的定义位置划分:

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

​ (1)定义及使用步骤:1.创建外部类对象;2.根据外部类对象创建内部类对象

​ (2)优势:内部类可以直接使用外部类的成员

​ (3)内部类编译后的结果:编译成的class文件样式:外部类名$内部类名.class

​ (4)可再次划分:

​ a.【静态内部类】由static修饰的成员内部类

​ 创建静态内部类对象格式:外部类名.内部类名 变量名 = new 外部类名.内部类名();

​ b.【实例内部类】无static修饰的成员内部类

​ 创建实例内部类对象格式:1、先创建外部类对象hh

​ 2、根据外部类对象创建内部类对象,

​ 【格式】:外部类名.内部类名 对象名 = hh.new 内部类名();

2、局部内部类:在类中方法内定义的类

​ (1)定义及使用步骤:1.创建外部类对象;2.在定义局部内部类之后,立马使用

​ (2)优势:内部类可以直接使用外部类的成员

​ (3)内部类编译后的结果:编译成的class文件样式:外部类名$数字内部类名.class //此处的数字表示该类中的第几个内部类

​ (4)可再次划分:

​ a.【局部内部类】`

​ b.==【匿名内部类】==没有名字的内部类

​ <1>创建格式:

new 接口或者类() {
    重写方法;
}.方法名();

​ <2>本质:

​ 四合一
​ 1.定义一个没有名字的类
​ 2.这个没有名字的类实现了前面的接口(接口方法由抽象变具体)
​ 3.创建了这个没有名字的类的对象
​ 4.对象调用了方法

在这里插入图片描述

​ <3>如果需要多次调用方法,需要保存这个匿名内部类创建的对象(实际上是运用了多态)

​ 格式:接口名 变量名 = new 实现类();

Smokeable sm = new Smokeable() {
    @Override
    public void smoking() {
        System.out.println("站着抽烟");
    }
};
sm.smoking();
sm.smoking();
sm.smoking();


<4>匿名对象的使用场景

​ 匿名内部类一般是作为参数传入。

​ (当方法参数是接口的时候,可以传入倪敏内部类对象,代码简单)

public class Demo10 {
    public static void main(String[] args) {
        Teacher t = new Teacher();
        Student s = new Student();

        goSwimming(t);
        goSwimming(s);

        // 方法的参数是接口,我们可以传入匿名内部类对象 =======================》重点!!!!!
        goSwimming(new Swimmable() {
            @Override
            public void swimming() {
                System.out.println("随便游");
            }
        });
    }

    //                                              接口名  变量名 = new 实现类();  多态
    // goSwimming(t);            Swimmable s = t;   Swimmable s = new Teacher();
    // goSwimming(s);            Swimmable s = s;   Swimmable s = new Student();
    // 我请一帮会游泳的人去游泳(很多人(对象)都可以去游泳,老师,学生等等,如果不使用接口作为方法参数,会让我们白白写很多重载方法。
    public static void goSwimming(Swimmable s) {
        s.swimming();
    }

    // public static void goSwimming(Teacher s) {
    // }
}

3、代码块

1静态代码块

定义位置:类中方法外

特点:静态代码块一个类只会自动执行一次

2实例(构造)代码块

定义位置:类中方法外

特点:构造代码块是在每次执行构造方法前自动执行

本质:经过反编译工具可知,实际上构造代码块里面的代码会放到构造方法的最前面

Person类:

public class Person {
    public static final int abc;
    // 静态代码块
    static {
        abc = 10;
        System.out.println("我是静态代码块");
    }

    // 构造代码块
    {
        System.out.println("我是构造代码块");
    }

    public Person() {
        System.out.println("我是Person的无参构造方法");
    }
}

测试类:

public class Demo11 {
    public static void main(String[] args) {
        // 创建两个对象
        Person p1 = new Person();
        Person p2 = new Person();
        Person p3 = new Person();
    }
}
/*
执行效果:
        我是静态代码块
        我是构造代码块
        我是Person的无参构造方法
        我是构造代码块
        我是Person的无参构造方法
        我是构造代码块
        我是Person的无参构造方法
*/

4、访问修饰符

public: 公开的,公共的
protected: 受保护的
(default)(什么都不写): 缺省|默认的
private: 私有的

修饰范围:public > protected > (default) > private

常用:
public: 所有地方都能使用
private: 只有本类能够使用

不常用的:
缺省的/默认的: 给同一包中的类使用
protected: 给子类使用的(无论本包还是其他包路径下的类)

5、Object类

1、概念:是所有类的父类,简称祖宗类。倘若一个类没有继承父类,其实是隐含继承了Object类。

​ (也就是说,所有的类都有Object类的成员方法)

2、Object类的toString()方法

​ (1)功能:返回对象的字符串表示:包名.类名@地址

​ (2)关于toString():

​ a.打印对象,其实就是打印对象toString方法的结果

Person p1 = new Person("菜虚?", 18);
// 打印对象,其实就是打印对象toString方法的结果
System.out.println(p1); //未重写前: com.itheima.demo15toString方法.Person@50cbc42f
System.out.println(p1.toString()); //未重写前: com.itheima.demo15toString方法.Person@50cbc42f

​ b.Arraylist类重写了toString()方法

​ c.系统重写toString(),会打印出该对象的成员变量(系统重写快捷键:Alt + insert ----> toString())

ArrayList<Integer> list = new ArrayList<>();
list.add(11);
list.add(22);
list.add(33);
System.out.println(list);//[11, 22, 33]
System.out.println(list.toString());//[11, 22, 33]

3、关于equals()方法

​ (1)功能:默认比较对象的地址,返回布尔类型值

​ (2)系统重写equals(),功能会发生改变,将会变成比较对象的内容,而不是地址值

6、Objects类

1、概念:Objects是对象的工具类,这个类是JDK1.7提供的,他里面的方法方便我们操作对象

2、Objects类中的equals()方法

​ static boolean equals(Object a, Object b)如果参数相等返回 true,否则彼返回false。

3、Objects类中的isNull()方法

​ static boolean isNull(Object obj) 判断对象是否为null,如果是null返回true

public static void main(String[] args) {
    Student s1 = new Student("凤姐", 18);
    Student s2 = new Student("凤姐", 18);

    s1 = null; // null表示没有保存任何对象的地址, null不能去调用方法

    if (s1 != null) { // 安全的判断,如果对象s1不为null,才去调用equals方法
        boolean b = s1.equals(s2);
        System.out.println("b = " + b);
    }

    // Objects类的eiquals在比较对象前会先判断s1是否为null,相当于上面的代码
    System.out.println(Objects.equals(s1, s2));

    // static boolean isNull(Object obj) 判断对象是否为null,如果是null返回true
    System.out.println(Objects.isNull(s1)); // true
    System.out.println(Objects.isNull(s2)); // false
}

未完待续。。

.println("b = " + b);
}

// Objects类的eiquals在比较对象前会先判断s1是否为null,相当于上面的代码
System.out.println(Objects.equals(s1, s2));

// static boolean isNull(Object obj) 判断对象是否为null,如果是null返回true
System.out.println(Objects.isNull(s1)); // true
System.out.println(Objects.isNull(s2)); // false

}


未完待续。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值