JAVA 类与对象

类与对象

  • 访问修饰符:public,protected,默认,private
  • 属性properties如果不赋值,有默认值,同数组默认值
如何创建对象
  • 先声明再创建

    Cat cat; cat = new Cat();

  • 直接创建

​ Cat cat = new Cat();

内存分配机制!

堆、栈、方法区

递归

重要规则
  • 执行一个方法是,会创建一个新的独立栈空间
  • 方法的局部变量相互独立,不互相影响
  • 方法使用引用变量类型时,会共享该引用类型数据

重载

  • 必须同名
  • 形参列表必须不一致(类型、个数、顺序至少有一个不同)
  • 返回类型无要求

可变参数

将同一类中多个同名同功能参数个数不同的方法封装为一个方法

  • 访问修饰符 返回类型 方法名(数据类型… 形参名)
  • 实参可以是0或者多个
  • 实参可以是数组
  • 可变参数本质是数组
  • 可以和普通类型参数一起放在形参列表,但是只能放在最后
  • 一个形参列表中只能出现一个可变参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5PAK5K65-1679030654950)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20221107103843851.png)]

作用域

  • 全局变量:属性,作用域为整个类体

  • 局部变量除属性之外的其他变量,作用域为定义它的代码块

  • 属性和局部变量可以重名,使用时遵循就近原则

  • 同一个作用域中,局部变量不能重名

  • 属性伴随对象的创建和销毁,局部变量伴随定义它的代码块的创建和销毁

  • 作用域范围不同

    • 局部变量:本类中对应的方法使用
    • 属性:本类或其他类使用
  • 修饰符不同

    • 属性可以加修饰符
    • 局部变量不能加修饰符

构造器constructor

  • 完成对新对象的初始化,不是创建对象,创建是new干的事情

  • 语法

    • [修饰符] 方法名(形参列表){

      ​ 方法体}

  • 修饰符可以默认,也可以 public protected private

  • 没有返回值

  • 方法名必须和类名相同

  • 参数列表和成员方法一样的规则

  • 构造器的调用由系统完成

  • 在创建对象时,系统自动调用该类的构造器完成对对象的初始化

  • 一个类可以定义多个不同的构造器,即构造器重载

  • 如果程序员没有定义构造方法,系统自动生成一个默认无参的构造方法

  • 一旦定义了自己的构造器,默认的构造器会被覆盖,不能再使用默认无参构造器,除非自己显式定义一下

创建对象流程分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fjOcPRY9-1679030654951)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20221107111305086.png)]

  1. 方法区加载Person类信息,只会加载一次

  2. 堆中分配空间(地址)存放对象

  3. 对象初始化:先进行默认初始化,属性的默认初始值,int为0,string为null;再显式初始化,age = 90;最后构造器初始化,实参传给n,把null换成小倩,小倩在常量池,把20赋值给age

  4. 把对象在堆区地址返回给栈区的p,p的本质是对象的引用(对象名),存储的是堆区的地址,对象应该是栈区开辟的空间

  5. person p2 = p1,意思是把堆区的地址赋值给p2

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cSuvjoF4-1679030654952)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20221107111202183.png)]

JAVA _this

  • java虚拟机会给每个对象分配this,代表当前对象

  • this.name是当前对象属性name,哪个对象调用就代表哪个对象

  • this是一个引用,是堆区的一种属性,指向自己

  • 细节

    • this可以用来访问本类的属性、方法、构造器
    • this用于区分局部变量与属性
    • 访问构造器语法:this(参数列表); 注意只能在构造器中使用,在一个构造器中访问另一个构造器,且必须放在第一句
    • this不能再类定义的外部使用,只能再类定义的方法中使用

访问修饰符modifier

  1. public:对外公开

  2. protected:子类和同一个包的类公开

  3. 默认:向同一个包的类公开

  4. private:只有类本身可以访问

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gZBJHVPH-1679030654952)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20221107161116137.png)]

  • 只有默认和public才能修饰类

封装encapsulation

实现步骤
  • 属性私有化
  • 提供公共的set方法,对属性判断并赋值
  • 提供公共的get方法,用于获取属性的值
  • 可以把set放在构造器中,限制设置的值

继承extends

解决代码复用

细节
  • 子类继承了所有的属性,但私有属性不能在子类直接访问,要通过公共方法去访问
  • 子类必须调用父类的构造器完成父类的初始化
  • 创建子类对象时,不管使用子类哪个构造器,默认情况下总会去调用父类的无参构造器,若父类没有提供无参构造器,则必须在子类构造器中用super指定使用父类的哪个构造器完成对父类的初始化工作
  • 希望 去调用父类的某个构造器,则显式的调用一下
  • super使用时需要放在构造器第一行
  • super(),this()都只能放在构造器第一行,因此两个方法不能共存在同一个构造器。
  • object是所有类的基类
  • 单继承机制,子类最多只能继承一个父类(直接继承)
  • 不能滥用继承
  • 内存:

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TOpoPKm2-1679030654952)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20221107174951414.png)]

  1. 加载类信息:object、grandpa、father、son

  2. 堆中分配内存空间:

    1. name:爷爷(存储在常量池)、hobby:旅游(存储在常量池)
    2. name:爸爸(存储在常量池)、年龄:39
    3. name:儿子(存储在常量池)
  3. 堆区中的空间地址分配给main栈中的son

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-64n5QwiA-1679030654952)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20221107174026414.png)]

当用son访问时,输出的应该是哪个名字?按照查找关系来返回信息

  1. 首先看子类是否有该属性:如果有且可以访问,则返回信息
  2. 如果子类没有该属性,则向上返回看父类是否有该属性且可以访问,则返回该信息
  3. 按照2规则继续向上查找,直到object,如果没有然后报错
super

代表父类的引用,用于访问父类的属性、方法、构造器

  • 可以访问父类的属性,不能访问父类的私有属性
  • 可以访问父类的方法,但不能访问父类的私有方法
  • 访问父类的构造器,只能放在构造器的第一句!

好处

  • 分工明确,父类属性由父类初始化,子类属性由子类初始化
  • 子类有父类成员重名时,为了访问父类的成员,必须通过super,如果没有重名,使用super、this、直接访问是一样的,如下:
  • 子类调用父类的方法时(属性同理)
    • cal(); 找cal方法顺序是先找本类,有则调用,没有则找父类,有则调用,无则继续寻找父类的父类;若找到了但是不能访问,则报错cannot access,若一直没有找到则提示方法不存在
    • this.cal(); 逻辑同cal();
    • super.cal(); 没有查找本类的过程,直接查找父类
  • super不限于直接父类,如果多个上级类都有同名成员则遵循就近访问原则
  • this和super的区别:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WvE2zKxD-1679030654953)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20221109162523951.png)]

重写 override

子类有一个方法和父类的一个方法的名称、返回类型、参数相同,即子类的这个方法覆盖了父类a的方法。

注意事项:

  • 子类的方法名称、参数必须与父类相同
  • 子类方法的返回类型和父类方法的返回类型一样,或者是父类返回类型的子类
  • 子类方法不难缩小父类方法的访问限权

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6re8fg1r-1679030654953)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20221109213526865.png)]

多态

方法或对象有多种形态,重写和重载体现了多态。

对象的多态
编译类型和运行类型
  1. 一个对象的编译类型和运行类型可以不一致

​ Animal animal = new Dog(); //编译类型Animal,运行类型Dog

​ animal = new Cat(); //运行类型变成Cat,编译类型仍是Animal

  1. 编译类型在定义对象时就确定了不能改变
  2. 运行类型是可以变化的
  3. 编译类型看 ’=‘左边,运行类型看’=‘右边
  4. 编译类型决定能调用哪个类的方法,如果调用子类的特有方法过不去编译,只能调用重写的方法(向上转型)
  5. 向下转型强制转换以后,编译类型改变为子类了,就可以调用子类的特有方法了
细节
  • 前提:两个对象具有继承关系

  • 向上转型:父类的引用指向了子类的对象 Animal animal = new Dog();

  • 语法:父类对象 对象名 = new 子类对象()

  • 编译阶段能调用哪些成员是由编译类型决定:可以调用父类的成员(遵守访问权限),不能调用子类特有成员(因为不能通过编译),可以调用重写的方法(通过编译以后,按照运行类型调用)

  • 向下转型:子类类型 引用名 = (子类类型) 父类引用;

    • Cat cat = (Cat) animal;
    • 此时cat的编译类型为Cat
  • 只能强转父类的引用,不能强转父类的对象

  • 父类引用必须指向的是当前目标类型的对象:animal原先的对象是猫,所以只能强转为猫

  • 可以调用子类类型中的所有成员

  • 属性没有转型之说,属性的值看编译类型

  • instanceOf:用于判断对象的运行类型是否为某某类型

动态绑定机制 Dynamic Binding
  • 调用对象方法时,该方法会和对象的运行类型/内存内存绑定

  • 调用对象属性时,没有动态绑定机制,哪里声明,哪里使用(找当前方法所在类的属性)

多态的应用
多态数组
参数多态

object类详解

equals方法

==:是一个比较运算符,不是一个方法,既可以判断基本类型(),也能判断引用类型(地址是否相等,即是否是同一个对象)。

equals:object类的一个方法,只能判断引用类型。默认判断地址是否相等。

hashcode

返回该对象的哈希码值。为了哈希表的性能。

  • 提高具有哈希结构容器的效率。
  • 两个引用,如果指向同一个对象,那么哈希值是一样的,
  • 两个引用如果指向不同对象,则哈希值是不一样的。
  • 哈希值主要根据地址计算,但不能等价于地址。
toString

返回该对象的字符串表示。默认返回:全类名(包名+类名)+ @ + 哈希的十六进制

finalize

垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类可以重写来做一些释放资源的操作。

系统自己决定调用时机,也可以用system.gc()主动触发垃圾回收机制。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值