Java封装
一、Java面向对象的三大特征
《1》封装:封装也称信息隐藏,是指利用抽象数据类型把数据和基于数据的操作封装起
来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能的隐藏数据
细节,只保留一些接口使其与外界发生联系。也就是说用户无需知道内部的数据和
方法的具体实现细节,只需根据留在外部的接口进行操作就行。
《2》继承:从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能
扩展新的能力。
《3》多态:方法的重写、重载与动态连接构成多态性。
二、封装
1、封装是指,一种将抽象性函式接口的实例细节部份包装、隐藏起来的方法。
封装防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,
必须通过严格的接口控制,通过该类提供的方法来实现对隐藏信息的操作和访问。
2、好处:
《1》只能通过规定的方法访问数据。
《2》隐藏类的实例细节,方便修改和实现。
3、实现类的封装的步骤:
《1》修改属性的可见性,在属性的前面添加修饰符
《2》对每个值属性提供对外的公共方法访问,如创建 getter/setter(取值和赋值) 方
法,用于对私有属性的访问
《3》在 getter/setter 方法里加入属性的控制语句,例如我们可以加一个判断语句,对
于非法输入给予否定。
三、包package
1、作用:
(1)把功能相似或相关的类或借口组织在同一个包中,方便类的查找和使用
(2)包采用了树形目录的存储方式。
同一个包中的类名字是不同的,不同的包中类的名字可以相同。
当调用两个不同包中相同类名的类时,应该加上包名加以区别。
(3)包限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
2、定义:
package 包名 //注意:必须放在源程序的第一行,包名可用"."号隔开
3、使用import关键字,在不同包中使用另一个文件中的类。
例如: import packagename.类名 ;
import 包名.* //将包下所有的文件都导入进来,*是通配符
4、包的命名:全小写字母拼音
四、访问修饰符
不同的访问修饰符的访问范围。
比如private修饰的属性或者方法,只能在当前类中访问或者使用。
默认是什么修饰符都不加,默认在当前类中和同一包下都可以访问和使用。
protected修饰的属性或者方法,对同一包内的类和所有子类可见。
public修饰的属性或者方法,对所有类可见。
五、this关键字
1、this关键字代表当前对象。
使用this.属性操作当前对象的属性,this.方法调用当前对象的方法。
六、内部类
1、(1)内部类:类的定义在另一个类(外部类)的定义内部
(2)内部类可以是静态static的,也可用public,default,protected和private修饰。
(而外部顶级类即类名和文件名相同的只能使用public和default)
(3)注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两
类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成
后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以
和外部类的相同。
2、作用:
(1)内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中
的其他类访问该类
(2)内部类的方法可以直接访问外部类的所有数据,包括私有的数据
(3)内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
(4)内部类允许继承多个非接口类型
3、成员内部类
//外部类People
public class People {
private String name = "LiLei"; //外部类的私有属性
//内部类Student
public class Student {
String ID = "20151234"; //内部类的成员属性
//内部类的方法
public void stuInfo(){
System.out.println("访问外部类中的name:" + name);
System.out.println("访问内部类中的ID:" + ID);
}
}
//测试成员内部类
public static void main(String[] args) {
People a = new People(); //创建外部类对象,对象名为a
Student b = a.new Student(); //使用外部类对象创建内部类对象,对象名为b
// 或者为
People.Student b = a.new Student();
b.stuInfo(); //调用内部对象的suInfo方法
}
}
成员内部类的使用方法:
(1)Student类相当于People类的一个成员变量,所以Student类(成员内部类)可以使
用任意访问修饰符
(2)Student类在People类里,所以访问范围在类里的所有方法均可以访问People的属
性(即内部类里可以直接访问外部类的方法和属性,反之不行)
成员内部类可以直接使用外部类的所有成员和方法,即使是private的。同时外部类要
访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。
(3)定义成员内部类后,必须使用外部类对象来创建内部类对象,
即内部类 对象名=外部类对象.new 内部类()
(4)如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或
方法,如果要访问外部类的成员变量,可以使用this关键字。例如:a.this
(5)成员内部类不能含有static的变量和方法,因为成员内部类需要先创建了外部类,才
能创建它自己的。
4、静态内部类(嵌套类)
//外部类People
public class People {
private String name = "LiLei"; //外部类的私有属性
/*外部类的静态变量。
Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。 */
static String ID = "510xxx199X0724XXXX";
//静态内部类Student
public static class Student {
String ID = "20151234"; //内部类的成员属性
//内部类的方法
public void stuInfo(){
System.out.println("访问外部类中的非静态变量name:" + (new People().name));
System.out.println("访问外部类中的静态变量ID:" +People.ID);
System.out.println("访问内部类中的ID:" + ID);
}
}
//测试成员内部类
public static void main(String[] args) {
Student b = new Student(); //直接创建内部类对象,对象名为b
b.stuInfo(); //调用内部对象的suInfo方法
}
}
结果:
访问外部类中的非静态变量name:LiLei
访问外部类中的静态变量ID:510xxx199X0724XXXX
访问内部类中的ID:20151234
静态内部类是static修饰的内部类。
静态内部类特点是:
(1)静态内部类不能直接访问外部类的非静态成员,但可以通过new 外部类().成员 的方式访问
(2)如果外部类的静态成员与内部类的成员名称相同,可以通过类名.静态成员 访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不同,则可通过成员名
直接调用外部类的静态成员。
(3)创建静态内部类的对象时,不需要外部类的对象,可以直接创建
内部类 对象名=new 内部类()
(4) 嵌套类和普通的内部类还有一个区别:普通内部类不能有static数据和static属性,也
不能包含嵌套类,但嵌套类可以。而嵌套类不能声明为private,一般声明为public,
方便调用。
5、局部内部类:内部类定义在方法和作用域内
//外部类People
public class People {
//定义在外部类中的方法内:
public void peopleInfo() {
final String sex = "man"; //外部类方法中的常量
class Student {
String ID = "20151234"; //内部类中的常量
public void print() {
System.out.println("访问外部类的方法中的常量sex:" + sex);
System.out.println("访问内部类中的变量ID:" + ID);
}
}
Student a = new Student(); //创建方法内部类的对象
a.print();//调用内部类的方法
}
//定义在外部类中的作用域内
public void peopleInfo2(boolean b) {
if(b){
final String sex = "man"; //外部类方法中的常量
class Student {
String ID = "20151234"; //内部类中的常量
public void print() {
System.out.println("访问外部类的方法中的常量sex:" + sex);
System.out.println("访问内部类中的变量ID:" + ID);
}
}
Student a = new Student(); //创建方法内部类的对象
a.print();//调用内部类的方法
}
}
//测试方法内部类
public static void main(String[] args) {
People b = new People(); //创建外部类的对象
System.out.println("定义在方法内:===========");
b.peopleInfo(); //调用外部类的方法
System.out.println("定义在作用域内:===========");
b.peopleInfo2(true);
}
}
输出结果:
定义在方法内:===========
访问外部类的方法中的常量sex:man
访问内部类中的变量ID:20151234
定义在作用域内:===========
访问外部类的方法中的常量sex:man
访问内部类中的变量ID:20151234
(1)局部内部类只在该方法或条件的作用域才能使用,退出这些作用域后无法引用。
6、匿名内部类
(1)匿名内部类:没有名字的内部类。
匿名内部类只能使用一次,通常用来简化代码编写。
使用匿名内部类的条件:必须继承一个父类或实现一个接口。
(2)
public class Outer {
public Inner getInner(finalString name, String city) {
returnnew Inner() {
private String nameStr = name;
public String getName() {
return nameStr;
}
};
}
public static void main(String[] args) {
Outer outer = new Outer();
Inner inner = outer.getInner("Inner", "NewYork");
System.out.println(inner.getName());
}
}
// 注释后,编译时提示类Inner找不到
interface Inner {
String getName();
}
//new 匿名类,这个类是要先定义的,如果不先定义,编译时会报错该类找不到
(1)匿名内部类是不能加访问修饰符的。
注意:new 匿名类,这个类是要先定义的,如果不先定义,编译时会报错该类找不到
(2)当所在的方法的形参需要在内部类里面使用时,该形参必须为final。
例如:形参name定义为final,而形参city没有被使用则不用定义为final。
(简单理解就是,拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,
而导致内部类得到的值不一致,于是用final来让该引用不可改变)
(3)匿名内部类没有名字,是用默认的构造函数(无参构造函数)。如果需要该类有带参
数的构造函数,示例如下:
public Inner getInner(final String name, String city) {
return new Inner(name, city) {
private String nameStr = name;
public String getName() {
return nameStr;
}
};
}
注意: 这里的形参city,由于它没有被匿名内部类直接使用,而是被抽象类Inner的构造函数所使用,所以不必定义为final。
参考链接: