1、封装
定义
封装就是把对象的属性(状态)和⽅法(⾏为)结合在⼀起,并尽可能隐蔽对象的内部细节,成为⼀个不可分割的独⽴单位(即对象),对外形成⼀个边界,只保留有限的对外接⼝使之与外部发⽣联系。
原则
使对象以外的部分不能随意存取对象的内部数据,从⽽有效的避免了外部错误对它的“交叉感染”。
数据隐藏特性提升了系统安全性,使软件错误能够局部化,减少查错和排错的难度。
2、类
定义
类就是对象的模板,⽽对象就是类的⼀个实例 。
类由属性和⽅法构成:
对象的特征在类中表⽰为成员变量,称为类的属性。
类的⽅法是对象执⾏操作的⼀种规范。⽅法指定以何种⽅式操作对象的数据,是操作的实际实现。
类的实现
[访问符][修饰符]class<;类名>{
[属性]
[⽅法]
}
//声明⼀个类,定义⼀个长⽅形(Rectangle)类,有长、宽属性,对每个属性都提供相应的get/set⽅法
public class Rectangle {
/* 长⽅形宽度 */
private double width;
/* 长⽅形⾼度 */
private double length;
/* 成员变量对应的⽅法 */
public double getWidth(){
return width;
}
public void setWidth(double width){
this.width = width;
}
public double getLength(){
return length;
}
public void setLength(double length){
this.length = length;
}
}
对象的创建
要获得⼀个类的对象⼀般需要两步:
1. 声明该类类型的⼀个变量。
2. 创建该对象(即在内存中为该对象分配地址空间),并把该对象的引⽤赋给声明好的变量。这是通过使⽤new运算符实现的。
类的构造⽅法
1. 构造⽅法是⼀种特殊的⽅法,在对象被创建时⽤来初始化对象;
2. 它具有和它所在的类完全⼀样的名字
3. 构造⽅法和类的⽅法类似,只不过构造⽅法没有返回类型;
4. 构造⽅法的任务是初始化⼀个对象的内部状态
5. 如果在Java程序中没有定义任何的构造⽅法,则编译器将会⾃动加上⼀个不带任何参数的构造⽅法即缺省构造⽅法,该⽅法不存在于
源程序中,但可以使⽤。
public class Rectangle {
private double width;
private double length;
/* 利⽤width和length创建构造⽅法 */
public Rectangle (double width,double length){
this.width = width;
this.length = length;
}
}
this对象的使⽤
this关键字代表当前所在类的对象,即本类对象,⽤于解决变量的命名冲突和不确定性问题;在没有同名的情况下,可以直接使⽤属性的名字。
参数传递
按值传递
按值传递(call by value) ,将要传递的参数的值传递给被调⽅法,被调⽅法通过创建⼀份新的内存拷贝来存储传递的值,然后在内存拷贝上进⾏数值操作,所以按值传递不会改变原始参数的值。⼀般传递的参数为基本数据类型(数值,字符)会⾃动采⽤按值传递
public static void main(String[] args){
int num =5;
System.out.println("调⽤change⽅法前 : "+ num);
//创建⼀个CallByValue类型的对象
CallByValue callByValue =new CallByValue();
callByValue.change(num);
System.out.println("调⽤change⽅法后 : "+ num);
}
/*定义change⽅法*/
public void change(int num){
num +=5;
System.out.println("在change中 num的值为 : "+ num);
}
//执⾏结果如下:
调⽤change⽅法前:5
在change中 num的值为:10
调⽤change⽅法后:5
引⽤传递
引⽤传递是将参数的引⽤传递给被调⽅法,被调⽅法通过传递的引⽤值获取其指向的内存空间,从⽽在原始内存空间上直接进⾏操作,即实参和形参指向内存中同⼀空间。⼀般传递的参数为对象时会⾃动采⽤引⽤传递。
class CallByRef {
int a, b;
CallByRef(int i,int j){
a = i;
b = j;
}
void change(CallByRef obj){
obj.a =50;
obj.b =40;
System.out.println("在change⽅法中 obj.a="+ obj.a +",obj.b="+ obj.b);
}
}
public class Test {
public static void main(String[] args){
CallByRef obj =new CallByRef(15,20);
System.out.println("调⽤change⽅法前 obj.a="+ obj.a +",obj.b="+ obj.b);
obj.change(obj);
System.out.println("调⽤change⽅法后 obj.a="+ obj.a +",obj.b="+ obj.b);
}
}
//执⾏结果如下:
调⽤change⽅法前 obj.a=15,obj.b=20
在change⽅法中 obj.a=50,obj.b=40
调⽤change⽅法后 obj.a=50,obj.b=40
⽅法重载
在Java程序中,如果同⼀个类中存在两个⽅法同名,⽅法的签名(参数个数、参数类型、类型排列次序)上也⼀样,将⽆法编译通过。但在Java中多个⽅法重名是允许的,只要保证⽅法签名不同即可,这种特性称为⽅法重载(overload)。
⽅法重载需遵循如下两条规则:
⽅法名相同
参数列表(个数、类型、顺序)不同;
注意:返回值不影响⽅法重载。构造⽅法也可以重载 。
3、包
包中类的访问
⼀个类可以访问其所在包的所有类。访问其他包的类有如下两种⽅式访问
//使⽤import语句导⼊要访问的类,如:
import java.util.*;
import mypackage.school.Student ;
//使⽤的类名前直接添加完整的包名,如:
java.util.Date now =new java.util.Date();
mypackage.school.Student tom =new mypackage.school.Student();
*注意:指明导⼊当前包的所有类,不能使⽤类似于java. 的语句来导⼊以java为前缀的所有包的所有类。
4、访问修饰符
Java中定义了private(私有的)、protected(受保护的)和public(公共的)的访问修饰符,同时也定义了⼀个缺省的访问级别,⽤于声明类、属性、⽅法的访问权限。明确访问修饰符的限制是⽤好“封装”的关键 :
1. 使⽤public访问修饰符,类的成员可被同⼀包或不同包中的所有类访问,也就是说,public访问修饰符可以使类的特性公⽤于任何
类;
2. 使⽤protected访问修饰符允许类本⾝、同⼀包中的所有类和不同包中的⼦类访问;
3. 如果⼀个类或类的成员前没有任何访问修饰符时,默认为friendly,它们获得缺省的访问权限,缺省的可以被同⼀包中的其他类访问;
4. private访问修饰符是限制性最⼤的⼀种访问修饰符,被声明为private的成员只能被此类中的其他成员访问,不能在类外看到。
Java中访问控制表
访问控制private成员缺省成员protected成员public成员
同⼀类中成员ÖÖÖÖ
同⼀包中其他类×ÖÖÖ
不同包中⼦类××ÖÖ
不同包中⾮⼦类×××Ö
5、静态变量和⽅法
·静态变量和⽅法
在Java中,可以将⼀些成员限制为“类相关”的,⽽前⾯介绍的成员是“实例相关”的。
“实例相关”的成员描述的是单个实例的状态和⽅法,其使⽤必须要通过类的实例来完成;
“类相关”是在类的成员前⾯加上“static”关键字,从⽽直接通过类名就可以访问 。
注意: 类的静态变量和静态⽅法,在内存中只有⼀份,供该类的所有对象共⽤。
public class InstanceCounter {
// ⽤于统计创建对象的个数
public static int count =0;
public InstanceCounter(){
count++;
}
// ⽤于输出count的个数
public static void printCount(){
System.out.println("创建的实例的个数为:"+ count);
}
public static void main(String[] args){
for(int i =0; i <100; i++){
InstanceCounter counter =new InstanceCounter();
}
InstanceCounter.printCount();
}
}
//执⾏结果如下:
创建的实例的个数为:100