首页 > 基础资料 博客日记

day08-fire

2025-09-04 22:30:01基础资料围观133

文章day08-fire分享给大家,欢迎收藏Java资料网,专注分享技术知识

重写/多态/类型转换/其他

重写

子类和父类拥有同名非静态(static)方法时会发生重写

父类的引用可以指向子类(和多态有关)

B类

package com.example.demo.oop.obj;

public class B {
    public void a(){
        System.out.println("B=>a()");
    }
}

A类

package com.example.demo.oop.obj;

public class A extends B {
    @override//注解:有功能的注释
    public void a(){
        System.out.println("A=>a()");
    }
}

Test 发生了重写了

package com.example.demo.oop.obj;

public class Demo03 {

    public void main(String[] args) {
        A a=new A();
        B b=new A();
        a.a();//A=>a()
        b.a();//A=>a()
    }
}
static的进一步:类和对象

当A,B类里的同名方法是static的时候,这时候输出结果就是A=>a()和B=>a(),这是因为static是类级别的,内存加载时会直接加载在堆空间。那么谁(A或B声明)就会指向谁的方法,这时候就没有发生重写。只有当其方法为非静态方法是,即对象级别的,那么new时就根据类名来确定方法。(和下面结合一下重写理解可能会更好)

关于重写和多态的问题

这里有个问题:父类的对象可以指向子类

这是 Java 中多态(Polymorphism) 的核心体现之一,语法上称为 “向上转型(Upcasting

本质是 “子类是父类的一种特殊形式”(比如 “狗是动物的一种”),符合 “is-a” 关系 —— 既然 Dog 属于 Animal 范畴,用 Animal 类型的变量来 “指代” Dog 对象,逻辑上完全成立

Q:A是B的子类,可以B a=new A(),但是不能A a =new B()对吧?就是可以说子像父,但是不能说父像子一样?

A:核心逻辑就是 “is-a” 关系的单向性,父类引用可以指向子类对象,子类引用不能指向父类对象

关于调用成员限制:只能调用父类中声明的成员

父类引用指向子类对象后,只能访问父类中定义的方法 / 属性,无法直接访问子类特有的方法 / 属性(除非通过 “向下转型” 强制转换类型)

简言之:父类引用能 “装” 子类对象,但只能用父类有的 “功能”

final & static

final确保工具类/方法不被修改,而static确定了其属于对象还是类级别

**summary: ** 重写

  1. 必须有继承关系
  2. 方法名要一致
  3. 修饰符可以扩大,但是不能缩小 private<default<protected<public
  4. 重写可能会抛出异常:范围可以被缩小,但是不能扩大(精细化,错误有粗略到详细)如:ClassNotFoundException --> Exception

为什么需要重写:

  1. 从一般出发,需求冲突,即子类需要的方法或者其他父类不能满足

快捷键:alt+ins可以重写方法,构造方法等等

多态

[!IMPORTANT]

多态的核心:“编译看左边,运行看右边”

在编译阶段,只看父类中是否有该方法,在运行时会调用实际指向的对象也就是子类,这就是多态的核心

对于子类A和父类B和基类Object

//一个对象的实际类型是一定的
//new A()
//new B()

//但是引用类型就不一定了,父类可以指向子类
//但是可以和(type)强制转换,把父类的对象引用强制转换为子类。这样也可以调用子类的方法

/*
多态注意事项:
	1.多态是方法的多态
	2.类型转换是需要有继承关系的(转换异常:ClassCastException)
	3.存在:
		继承关系
		方法重写
		父类的引用指向子类
**/

我的粗浅理解:从内存分配来说,在编译时有标识身份的类来说明,编译查看声明类是否有该方法,没有就直接报错。在运行时,根据关键字new创建的空间来确定引用实际指向的方法。如果子类没有就向去父类里面找。

方法加载一次,跟着类走,属性跟着对象走,每个对象一份。只是非static的方法依赖于对象来调用而已

子类的加载依赖于父类的加载,先父后子嘛

instanceOf 和类型转换

x instanceOf y:

  1. x和y有继承关系才会编译通过
  2. 真假值和x实例是不是y的子代

类型转换高转低要强转

  1. 父类的引用指向子类的对象

  2. 如果调用身份不符的方法的话就无法调用,所以需要类型转换

  3. B obj = new A()//A里有自己的方法go()
    ((A) obj).go()//这样强转身份就可以调用子类的方法了
    
  4. 子类转换为父类可能会丢失一些方法

static

{
	System.out.println("匿名代码块,用于复初值,先于构造方法,且没new一个实例都会再运行一次")
}

static{
	System.out.println("static代码块,于类同时,最先执行且只执行一次,因为是类级别的,然后才是main方法")
}

类加载和初始化

jvm先找到类的main方法,但是在执行main方法前必须对类进行初始化,包括了static代码块

只有初始化类后才执行main方法,这就是为什么先输出static块再输出main的原因

静态导入包 import static Java.lang.Math.max

😘


文章来源:https://www.cnblogs.com/billmu/p/19074498
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云