Java学习笔记——第五章对象封装
第五章 对象封装
5.1 何为封装
5.1.1 封装对象初始流程
如果想存取对象的数据成员,可以通过“.”运算符加上数据成员名称。
构造函数是与类名称同名的方法,不用声明返回类型。
class CashCard{
String number;
int balance;
CashCard(String number, int balance){
this.number = number;
this.balance = balance;
}
}
使用this关键词,将类的number、balance参数值,指定给调用对象(this)的number,balance数据成员。
5.1.2 封装对象操作流程
在类中定义方法,如果不用返回值,方法名称前可以声明void,如果方法会返回值,必须在方法前声明返回值的类型,使用return返回返回值。例如:
...(省略)
void store(int money){
if(money > 0){
this.balance = balance;
}else{
...(省略)
}
}
int exchange(int bonus){
if(bonus > 0){
this.bonus -= bonus;
}
return this.bonus;
}
5.1.3 封装对象内部数据
如果有些数据是类私有的,在Java中可以使用private关键词定义。
如果没有提供方法存取private成员,用户就不能进行存取。要想存取私有成员的值,必须提供相应的get、set方法!
在IDE中,可以自动生成构造器和相应的方法。
小结
封装的主要目的是隐藏对象细节,将对象当做黑箱进行操作,比如用户调用构造函数,但不知道构造函数的具体细节,调用相应的方法,但不知道方法的流程,用户也不知道有哪些私有的数据,要操作对象,要通过提供的方法调用。
private也可以用在方法或构造函数声明上,私有方法或构造函数通常是类内部某个共享的演算流程,外界不知道私有方法的存在。private也可以用在内部类的声明上。
5.2 类语法细节
5.2.1 public权限修饰
声明为private的成员表示为类私有,用户无法在其他类的程序代码中直接存取;如果没有声明权限修饰的成员,只有在相同包的类程序代码中才可以直接存取,也就是包范围权限;如果想在不同包的类程序代码中存取某包的类或对象成员,则该类或对象成员必须是公开成员,即用public声明。
包管理还有权限上的概念,没有定义任何权限关键字的就是包权限。在Java中,有private、protected和public三个权限修饰符。
5.2.2 关于构造函数
构造函数是与类名称同名,无需声明返回类型的方法。
如果定义类时,没有撰写任何构造函数,编译程序会自动加入一个无参数、内容为空的构造函数。
注:只有编译程序自动加入的构造函数才称为默认构造函数,如果自行撰写无参数、没有内容的构造函数就不称为默认构造函数了。
public class Some{
private int a = 10;
private String text;
public Some(int a, String text){
this.a = a;
this.text = text;
}
}
创建对象时,数据成员就会初始化,如果没有指定默认的初始值,则会使用默认值初始化。
5.2.3 构造函数与方法重载
一个类中可以定义多个构造函数,只要参数类型或个数 不同,这称为重载构造函数。例如,如下称为重载,调用时根据不同传递参数的不同,调用对应的方法。
public static String valueOf(boolean b)
public static String valueOf(char c)
public static String valueOf(char[] data)
public static String valueOf(double d)
public static String valueOf(double e, double f)
...
注:
1、返回值类型不可以作为方法重载的依据。以下不能成为重载!
public class Some{
public int someMethod(int i){
return 0;
}
public double someMethod(int i){
return 0.0;
}
}
2、在JDK5之后使用方法重载时,要注意自动装箱、拆箱问题,例如:
class Some{
void someMethod(int i){
System.out.pringln("start1");
}
void someMethod(Integer integer){
System.out.pringln("start2");
}
}
public class Test{
public static void main(String[] args){
Some s = new Some();
s.someMethod(1);
}
}
结果会显示start1,如果想调用参数为Integer的方法,需要明确指明,例如:s.someMethod(new Integer(1));
编译程序在处理重载方法时,会依以下顺序来处理:
(1)还没有装箱动作前可符合自变量个数与类型的方法;
(2)装箱动作后可符合自变量个数与类型的方法;
(3)尝试有不定长度自变量并可符合自变量类型的方法;
(4)找不到合适的方法,编译错误。
5.2.4 使用this
除了被声明为static的地方外,this关键词可以出现在类中的任何地方,在对象建立后为这个对象的参考名称。
在Java中,this()代表调用另一种构造函数,至于调用那个构造函数,则视调用this()时给的自变量类型与个数而定。
this()调用只能出现在构造函数的第一行。
...(省略)
public Some(int a){
this.a = a;
}
public Some(int a, String text){
this(a);
this.text = text;
}
如果撰写了对象初始化块,对象建立后会执行对象初始化块,然后才调用指定的构造函数。
如果局部变量声明了final,表示设值后就不能在变动,对象数据成员也可以声明final。
如果对象数据成员被声明为final,但没有明确使用=指定值,表示延迟对象成员值的指定,在构造函数执行流程中,一定要有对该数据成员指定值的操作,否则编译错误!
5.2.5 static类成员
当某个属性值为固定常数,不必每个对象各自拥有,可以在其前面声明static,表示它属于类,不被个别对象拥有。
class Ball{
double radius;
static final double PI = 3.14;
static double toRadians(double angdeg)
return angdeg * (Ball.PI / 100);
}
对于被声明为static的成员,将类名称作为名称空间,可通过类名称.属性或 类名称.方法的方式获取对应的内容。例如:
Ball.PI;或Ball.toRadians(100);
注:
1、在static方法或区块中,不能出现this关键词(因为static属性或方法随着类的加载而加载,this在类创建对象后才可使用);
2、在static方法或区块中,不能调用非static方法或区块;
3、在static方法或区块中,可以使用static数据成员或方法成员。
5.2.6 不定长度自变量
要使用不定长度自变量,声明参数列时要在类型关键词后加上...。
使用不定长度自变量时,方法上声明的不定长度参数必须是参数列最后一个,使用两个以上不定长度自变量也是不合法的。以下内容是合法的:
public void some(int arg1, int arg2, int... arg3)
以下声明是不合法的:
public void some(int... args, int... args)
public void some(int... args, int args)
5.2.7 内部类
可以在类中再定义类,称为内部类。
建立非静态的内部类,调用时先建立外部类的对象,通过外部类的对象调用,例:
class Some{
class Other{
}
...
调用:
Some s = new Some();
Some.Other o = s.new Other();
}
一个被声明为stati的内部类,在JVM加载时即加载,可通过类名.内部类名的方式调用。
class Some{
static class Other{
}
...
调用:
Some.Other o = new Some.Other();
}
5.2.8 传值调用
在Java中只有传值调用。