Java:面向对象概念(构造函数,继承,this ,super关键字)

构造函数 构造器

构造方法:
  • 构造方法必须具备和所在类相同的名字
  • 构造方法没有返回值,void也没有
  • 构造方法是在创建一个对象使用new操作符时调用的(初始化对象)

构造方法具有和定义它的类完全相同的名字,构造函数也可以重载
在定义中如果出现其他的构造函数,则默认的无参构造函数不存在(建议写出无参构造函数)
如果一个类里面没有定义任何构造函数,则会有一个隐藏的无参构造函数
权限修饰符 类名(参数列表){
return;
}

构造函数和成员函数的区别
  • 外界调用角度
  • 构造函数:(一次)只能在创建对象时调用,对象创建完毕之后不能已创建的对象调用
  • 成员函数:(多次)只能在对象创建之后调用,可以重复使用
  • 返回值
  • 构造函数:没有返回值
  • 成员函数:可有可没有
  • 权限修饰符
  • 构造函数:可以用任意权限修饰符
  • 成员函数:也可使用任意权限修饰符
  • 内部调用
  • 1.构造函数调用成员函数 --> 可
  • 但是不推荐(这里的成员函数一般不会当做对象的行为去看待)
  • 2.构造函数调用构造函数 --> 可
  • this(参数列表)调用当前类中的其他构造函
  • 构造函数之间不能相互调用(出现无限递归)
  • this(…)必须在第一句 —> 防止值的覆盖
  • 3.成员函数调用成员函数 —> 可
  • 4.成员函数能否调用构造函数 —> 不能
  • 可使用new (构造函数可以与成员函数重名)
对象的创建流程

对象的创建流程

Created with Raphaël 2.2.0 堆内存中开辟一个空间,分配地址 对成员变量进行默认初始化 相应的构造函数进栈,此时先进行显示初始化 接着在执行构造函数中的内容,针对性初始化 构造函数执行完毕弹栈 将对象的地址传给相应的变量

成员变量和局部变量

成员变量:对象的特有属性
局部变量:函数中所创建的变量

1. 存储位置
成员变量:存在于内存中对象的所属空间里
局部变量:存在于内存中函数的所属空间里
2. 生命周期
成员变量:随着对象的创建而存在,随着对象的销毁而消失
局部变量:随着函数的进栈而进栈,随着函数的弹栈而消失
3. 初始化
成员变量:【默认初始化,显示初始化,针对初始化】
局部变量:必须初始化在能够被调用
4. 作用域
成员变量:全局可用
局部变量:在其最近的一对 { } 中
for(int i=0;i<n;i++){

}

静态变量和成员变量

1. 存储位置
静态变量:在静态方法区中类所属的空间里
成员变量:在堆内存中对象的所属空间里
2. 生命周期
静态变量:随着类(.class文件)的加载而存在,随着程序的结束而结束
成员变量:随着对象的创建而存在,随着对象的消亡而消亡
3. 调用方式
静态变量:可以对象调用,类调用
成员变量:只能对象调用
4. 别名
静态变量:属于类,也称作成员
成员变量:属于对象,也称作对象的特有属性

static关键字

1. 概念:

静态关键字:可以修饰成员变量-静态变量
如果若干个同种类对象当中存在相同的属性值的话
那么这个属性就可以抽离出来定义为静态变量
饮水机 —— 学生 —> 静态一般要比对象的生命周期长

想让一个类的所有实例共享数据,就要使用静态变量,也称为类变量。(静态变量将变量存储在一个公共的内存地址)
在这里插入图片描述

(静 —> 静)静态方法可以调用静态方法以及访问静态数据域。
(静 --×-> 实)静态方法不能调用实例方法或者访问实例数据域

2. 如何判断一个变量或方法应该是实例的还是静态的?
如果一个变量或方法依赖于类的某个具体实例(实例变量或实例方法)
如果一个变量或方法不依赖于类的某个具体实例,那就应该将它定义为静态变量或静态方法

可以修饰成员函数 – 静态函数(不直接调用成员)
静态成员是类成员,由类直接调用
特有成员是对象成员,由对象直接可以调用
静态成员也可以直接由对象调用

final 关键字

修饰变量
凡是对成员变量或者局部变量(在方法中的或者代码块中的变量称为本地变量)声明为final的都叫作final变量。final变量经常和static关键字一起使用,作为常量。

final int a=3;
final int[] arr=new int[10];
final修饰类 该类不能被继承
final修饰函数 该函数不能被重写

final修饰基本数据类型的变量时,必须赋予初始值且不能被改变,修饰引用变量时,该引用变量不能再指向其他对象

对象创建流程

Created with Raphaël 2.2.0 javac 编译 Main.java生成两个字节码文件 Main.class Person.class java 运行 Main.class 将Main.class 和Person.class 文件加载进JVM 具体加载进了——方法区 内存: 1. 寄存器:直接与CPU进行数据交互 2. 本地方法区:主要临时存储OS的可执行代码 3. 方法区:主要临池存储APP的可执行代码 4. 栈:函数栈,用于运行函数 5. 堆:对象堆,主要存储对象数据 方法区分为: 静态方法区:主要存放 静态变量,静态函数 非静态方法区:主要存放 构造函数,成员 java Main 让虚拟机在静态方法区中的Main所属空间里找主函数 将主函数加载进栈,开始运行 执行主函数中的第一句 在堆内存中开辟相应的空间并分配地址 按照类的描述,创建成员变量并对其进行默认初始化 相应的构造函数,从非静态方法区中的相应的类空间里读取并加载进栈 构造函数刚刚进栈,则进行显示初始化 开始执行构造函数中的代码,针对性初始化 为了区分哪个对象调用的这个函数,this 指针 构造函数执行完毕弹栈,将对象的地址赋予左边 在主函数中创建Person类型的p变量空间 空间内存放的是该对象的地址 p对象调用speak()方法,则从非静态方法区中加载speak()的代码进栈 同样this 作为区分 成员函数中打印变量 **【局部——堆——静态方法区】**就近原则 operation: 在调用静态成员是,可以直接去静态方法区中找 Person.xxx Person 是因为该区域有多个类空间,我们需要指定一个 静态函数中打印变量【局部——静态】与堆无关,静态函数中没有this

代码块

  1. 静态代码块
  2. 构造代码块

局部代码块是函数中的一对 { }
for{}
while{}
if{}
switch{}

单例模式

设计模式:20+种,它不是随着Java的诞生而诞生的
(开发技巧,适用于一些特定的场合)
单例模式
代理模式
装饰模式
策略模式
工厂模式
观察者模式
单例模式的场合:适用于全局内,对象保持唯一性(当朝皇帝)
再简单点来说 一个类 只能被创建一个对象

  1. 如何创建对象
    new关键字用于创建对象,但不可随意进行new
    禁止外界调用构造器:构造器+private
  2. 组织外界创建对象,对象要存在
    内部创建——静态
  3. 外界依旧可以修改 +private
  4. 构造器+private 外界不可访问 getter

继承

1. 概念:
不同的类可能也会有一些共同的特征和行为,这些共同的特征和行为都统一放在一个类中,可以被其他类所共享。

父类和子类之间的关系 继承关系 extends
父类和子类之间必须是 is a 关系
is a 同一种类
继承之间是有传递性的
A->B->C

如图,显示了这些类之间的关系,指向父类的三角箭头用来表示 相关的两个类之间的继承关系。

继承关系

Circle 类继承了 CeometricObject 类所有可以访问的数据域和方法。除此之外,它还 有一个新的数据域 radius, 以 及 与 radius 相关的 get 和 set 方法。它还包括 getArea()、getPerimeter()和 getDiameterO 方法以返回圆的面积、周长和直径。
Rectangle 类从 CeometricObject 类继承所有可访问的数据域和方法。此外,它还 有 width 和 height 数据域,以及和它们相关的 get 和 set 方法。它还包括 getArea()和getPerimeter()方法返回矩形的面积和周长。

2. 关键点

  • 与传统不同,子类并不是父类的一个子集,通常情况下,子类比父类包含更多方法
  • 父类中的私有数据域在该类之外不可访问(若父类中定义了公共的访问器 / 修改器,可以通过这些来访问和修改他们)
  • 不是所有的 “是一种”(is-a)关系都该用继承来建模。
    例如:正方形是一种矩形,但是不应该定义一个 Square 类来扩展Rectangle 类,因为 width 和 height 属性并不适 合于正方形。应该定义一个继承自 CeometricObject 类的 Square 类,并为正方形的 边定义一个 side 属性
  • 一个父类和它的子类之间必须存在“是一种”(is a)关系
  • 某些程序设计语言是允许从几个类派生出一个子类的。这种能力称为多重继承。**但是在 Java中是不允许多重继承的。**一个 Java类只可能直接 继承自一个父类。这种限制称为单一继承,但是多重继承是可以通过接口来实现的

Java当中的继承
类与类之间是 单继承 接口与接口之间是 多继承
在Java里面我们会有一个最终的父类
Object类 是任何一个类的最终父类

3. 父类子类之间,成员特点

  • 成员变量
    父类中有(非私有) 子类中没有 —> 访问父类的
    父类中没有 子类中有 —> 访问子类的
    父类中有(非私有)子类中有 —> 访问子类的
    父类中有(非私有)子类有同名静态变量 —> 访问子类静态的
    this 存的是当前对象的地址,用于区分调用者
    super 指向的是其父类(字节码)空间
    局部 --> 子类成员变量(堆)—> 子类静态变量(静态区)
    —> 父类成员变量(非静态父类空间非静态父类空间)—> 父类静态变量(静态区)
  • 构造函数
    父类的构造函数会优先于子类的构造函数运行(父类为子类准备一些数据)
    构造函数的第一句有隐藏的super(参数列表)
    对于super(参数列表)调用,前提是父类必须有相应的构造函数
    this(…)也在第一句 不冲突
    因为this(…)会转接到其他构造函数,其他的构造函数最终不会再转接回去,第一句只能是super(…)
  • 成员函数
    子父类当中存在重名函数(非私有,参数列表页相同)<— 函数的重写
    重写意义:保留父类的函数声明(功能),子类对功能进行改进
    子类重写函数的权限 至少大于等于父类函数(非私)的权限
    //一旦有private就不考虑继承

supper关键字

1. 概念
关键字super指代父类,可以用于调用父类中的普通方法和构造方法

2. super用于两种途径
1)调用父类的构造方法
2)调用父类的方法

3. 调用父类的构造方法
构造方法用于构建一个类的实例。
不同于属性和普通方法,父类的构造方法不会被子类 继承。它们只能使用关键字 super 从子类的构造方法中调用。
调用父类构造方法的语法是:
super ( ) 或者 super ( parameters );
在这里插入图片描述

警告:
要调用父类的构造方法必须使用关键字super,并且这个调用必须是构造方法中的第一条语句。

4. 调用父类的方法

super. 方法名(参数);
在这里插入图片描述

object 类
  1. 提示:Java中所有的类都继承来自java.lang.Object类
  2. 如果在定义一个类时没有指定继承性,那么这个类的父类就被默认为师Object,例如:
    在这里插入图片描述
  1. Class<?> getClass()
    获取该类的字节码文件对象(xxx.class)
  2. int hashCode()
    哈希表 哈希函数 默认以对象的物理内存地址作为哈希值
  3. boolean equals(Object obj)
    Obj的equ默认比对象之间的地址!
    new Person 张三 10
    new Person 张三 10
  4. Object clone()
    对象的复制(浅复制)
  5. String toString()
    返回该对象的字符串表现形式
  6. void finalize()
    当对象被垃圾回收期回收时,调用此函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值