类与对象的基本概念(下)
文章目录
一、类的访问权限控制
类型 | private | 无修饰 | protected | public |
---|---|---|---|---|
同一类 | 是 | 是 | 是 | 是 |
同一包中的子类 | 否 | 是 | 是 | 是 |
同一包中的非子类 | 否 | 是 | 是 | 是 |
不同包中的子类 | 否 | 否 | 是 | 是 |
不同包中的非子类 | 否 | 否 | 否 | 是 |
1.访问控制修饰符
(1)默认访问修饰符-不使用任何关键字
仅允许同一个包内的访问;又被称为“包(package)访问权限”
使用默认访问修饰符声明的变量和方法,对同一个包内的类是可见的。
接口里的变量都隐式声明为 public static final
,而接口里的方法默认情况下访问权限为 public
。
(2)私有访问修饰符-private
只可被同一类的方法访问
私有访问修饰符是最严格的访问级别,所以被声明为 private
的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private
。
声明为私有访问类型的变量只能通过类中公共的 get
方法被外部类访问。
Private
访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。
(3)受保护的访问修饰符-protected
只可被同一类及其子类的方法访问
protected
需要从以下两个点来分析说明:
-
子类与基类在同一包中:被声明为
protected
的变量、方法和构造器能被同一个包中的任何其他类访问; -
子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的
protected
方法,而不能访问基类实例的protected
方法。
protected
可以修饰数据成员,构造方法,方法成员,不能修饰类(内部类除外)。
接口及接口的成员变量和成员方法不能声明为 protected
。
(4)公有访问修饰符-public
可以被其他任何方法访问(前提是对类成员所属的类有访问权限)
被声明为 public
的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的 public
类分布在不同的包中,则需要导入相应 public
类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。
2.set、get方法
(1)set方法
-
功能是修改属性变量的值
-
set方法名以“set”开头,后面是实例变量的名字(首字母大写)
-
例如:
public void setRadius(int r){ radius = r; }
(2)get方法
-
功能是取得属性变量的值
-
get方法名以“get”开头,后面是实例变量的名字(首字母大写)
-
例如:
public int getRadius(){ return radius; }
3.this关键字
-
1.普通的直接引用
this 是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。 -
2.形参与成员名字重名,用 this 来区分
如果方法内的局部变量(包括形参)名与实例变量名相同,则方法体内访问实例变量时需要this关键字public void setRadius(int radius){ this.radius = radius; }
二、对象初始化和回收
• 对象初始化
系统在生成对象时,会为对象分配内存空间,并自动调用构造方法对实例变量进行初始化
• 对象回收
对象不再使用时,系统会调用垃圾回收程序将其占 用的内存回收
1.对象初始化
构造方法用来初始化对象,每个类都需要有构造方法
- 方法名与类名相同;
- 不定义返回类型;
- 通常被声明为公有的(
public
); • 可以有任意多个参数; - 主要作用是完成对象的初始化工作;
- 不能在程序中显式的调用;
- 在生成一个对象时,会自动调用该类的构造方法为新对象初始化;
- 若未显式声明构造方法,编译器隐含生成默认的构造方法。
- final实例变量可以在类中定义时给出初始值,或者在每个构造方法结束之前完成初始化; final类变量必须在声明的同时初始化。
(1)默认构造方法
- 没有参数(内部类除外),方法体为空;
- 使用默认的构造方法初始化对象时,如果在类声明中没有给实例变量赋初值,则对象的属性值为零或空;
- 一旦定义了自己的构造方法,默认构造方法就会失效。
(2)自定义构造方法与方法重载
一个类中有两个及以上同名的方法,但参数表不同,这种情况就被称为方法重载。在方法调用时,可以通过参数列表的不同来辨别应调用哪一个方法。
- 只要显式声明了构造方法,编译器就不再生成默
认的构造方法。 - 也可以显式声明无参数的造方法,方法体中可以
定义默认初始化方式。
//为BankAccount声明一个有三个参数的构造方法
public BankAccount(String initName, int initAccountNumber, float initBalance) {
ownerName = initName;
accountNumber = initAccountNumber;
balance = initBalance;
}
//假设一个新帐号的初始余额可以为0,则可增加一个带有两个参数的构造方法
public BankAccount(String initName, int initAccountNumber) {
ownerName = initName;
accountNumber = initAccountNumber;
balance = 0.0f;
}
//无参数的构造方法——自定义默认的初始化方式
public BankAccount() {
ownerName = "";
accountNumber = 999999;
balance = 0.0f;
}
声明构造方法时使用this关键字:
- 可以使用this关键字在一个构造方法中调用另外的构造方法;
- 代码更简洁,维护起来也更容易;
- 通常用参数个数比较少的构造方法调用参数个数最多的构造方法
public BankAccount() {
this("", 999999, 0.0f);
}
public BankAccount(String initName, int initAccountNumber) {
this(initName, initAccountNumber, 0.0f);
}
public BankAccount(String initName, int initAccountNumber,float initBalance) {
ownerName = initName;
accountNumber = initAccountNumber;
balance = initBalance;
}
2.内存回收
- 当一个对象在程序中不再被使用时,就成为一个无用对象,将在必要时被自动回收
- Java运行时系统通过垃圾收集器周期性地释放无用对象所使用的内存。
- Java运行时系统会在对对象进行自动垃圾回收前,自动调用对象的finalize()方法。
(1)垃圾收集器:
- 自动扫描对象的动态内存区,对不再使用的对象做上标记以进行垃圾回收
- 作为一个后台线程运行,通常在系统空闲时异步地执行。
(2)finalize()方法:
-
在类java.lang.Object中声明,因此 Java中的每一个类都有该方法:
protected void finalize() throws throwable
-
用于释放资源。
-
类可以覆盖(重写)finalize()方法。
-
finalize()方法有可能在任何时机以任何次序执行。