封装与隐藏
为何需要封装
image.png
问题的引入:
当我们创建一个对象之后,可以通过点方法对对象的属性进行赋值操作,在这里,赋值操作仅收到对象属性的数据类型和存储范围的制约
但是实际问题中,我们往往需要添加其它更为确切的限制条件,而这些条件无法在属性声明的时候体现,因此只能使用方法来添加条件限制
同时,我们也需要避免用户通过点方法直接调用对象的属性,所以需要将属性设置为私有(private)
——> 以上,就是针对于属性的封装性的体现
image.png
如何封装和隐藏
image.png
这是一个实例:
public class AnimalTest {
public static void main(String[] args) {
Animal a = new Animal();
a.name = "大黄";
a.age = 1;
a.setLegs(4);
a.show();
a.setLegs(-3);
a.show();
// a.legs = 3; // The field Animal.legs is not visible
// 无法直接调用属性
}
}
class Animal{
String name;
int age;
private int legs; // 腿的个数,权限修饰为私有类型
public void setLegs(int l){ // 这个函数即为接口,通过它可以完成对legs赋值,但必须满足一定要求
if(l >= 0 && l % 2 == 0){
legs = l;
}else{
legs = 0;
// 异常处理
}
}
public int getLegs(){ // 同样为接口,用于获取属性值
return legs;
}
public void show(){
System.out.println("name = " + name + ",age = " + age + ",legs = " + legs);
}
}
四种权限访问修饰符
image.png
暂时不考虑protected,仅考虑其它三种关键字访问权限大小,请看以下例子:
package com.atguigu.java;
public class order {
private int orderPrivate;
int orderDefault;
public int orderPublic;
private void methodPrivate() {
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
void methodDefault() {
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
public void methodPublic() {
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
}
接着我们在同一个包定义另外一个类:
package com.atguigu.java;
public class orderTest {
public static void main(String[] args) {
order o = new order();
// 处于同一个包的类,无法调用private修饰的属性和方法
o.orderDefault = 1;
o.orderPublic = 2;
// o.orderPrivate = 3
o.methodDefault();
o.methodPublic();
// o.methodPrivate();
}
}
然后,我们创建一个新的包,并在其下面创建一个新的类:
package orderTest;
import com.atguigu.java.order;
public class orderTest {
public static void main(String[] args) {
order o = new order();
// 处于不同包的类,无法调用private和缺省修饰的属性和方法
// o.orderDefault = 1;
o.orderPublic = 2;
// o.orderPrivate = 3
// o.methodDefault();
o.methodPublic();
// o.methodPrivate();
}
}
总结:java提供了四种具体的权限修饰符来修饰类以及类的内部结构,体现出类以及类的内部结构在被调用时的可见性大小
构造器
构造器的特征和作用
image.png
构造器也叫作构造方法(函数),但必须将其与方法(函数)进行区分,这是两个完全不同的概念,而且作用也完全不一样
如果声明并使用构造器
请看下面的例子:
public class PersonTest {
public static void main(String[] args) {
Person p = new Person();
// 这里,Person()就是构造器
p.eat();
// 利用构造器初始化属性
Person p1 = new Person("Omew");
System.out.println(p1.name);
Person p2 = new Person("Kana", 16);
System.out.println("name: " + p2.name + ", age: " + p2.age);
}
}
class Person{
String name;
int age;
// 构造器
public Person(){
System.out.println("Person()...");
}
public Person(String n){
name = n;
}
public Person(String n , int a){
name = n;
age = a;
}
// 方法
public void eat(){
System.out.println("eating...");
}
public void study(){
System.out.println("studying...");
}
}
注意:
- Java语言中,每个类都至少有一个构造器(即系统提供的隐式无参构造器)
- 默认构造器的修饰符与所属类的修饰符一致
- 一旦显式定义了构造器,则系统不再提供默认构造器
- 一个类可以创建多个重载的构造器
- 父类的构造器不可被子类继承
构造器重载
image.png
(补充)赋值过程的先后顺序
image.png
this
image.png
this关键字的引入
当this修饰属性和方法时:
- this 可以理解为当前对象 或 当前正在创造的对象
- 在类的方法中,我们可以使用this关键字来调用当前对象的属性和方法,不过一般情况下都会省略
- 但是特殊情况下:比如形参和类的属性重名时,我们可以使用this关键字来区分出类的属性,而不是形参
当this修饰构造器时:
- 在类的构造器中,可以显式的使用this关键字,调用指定类的其它构造器
- 构造器中不能通过this关键字来调用自己本身
- 如果一个类中有n个构造器,则最多有n - 1构造器使用this关键字
- 如在构造器中需要使用this关键字调用其它构造器,则必须放在首行
- 构造器内部最多只能声明一个this关键字来调用其它构造器
请看下面例子,更好的理解this在方法和构造器中所起的作用
public class ThisTest {
public static void main(String[] args) {
People p1 = new People("Omew");
System.out.println(p1.getName());
People p2 = new People("Kana",16);
System.out.println(p2.getName() + " " + p2.getAge());
}
}
class People{
private String name;
private int age;
//构造器
public People(){
System.out.println("虽然不知道这段文字有什么意义,但却是非常重要的部分,因此请确保每个构造器都要输出以下文字:");
System.out.println("这是重要段落...");
System.out.println("这是重要段落...");
System.out.println("这是重要段落...");
}
public People(String name){
this(); // 调用空参构造器,这样就不用写上面那段重复代码了
this.name = name;
}
public People(String name, int age){
this(name); // 同理,这样就不用写那段重复代码了,同时还省略了name的赋值操作
this.age = age;
}
// 方法
public void setName(String name){
this.name = name; // 必须指明this,否则引起歧义
}
public String getName(){
return this.name; // 可省略this
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
package
image.png
package 关键字使用
- 为了更好地对项目中的类进行管理,提出了包的概念
- 使用package声明类或接口所属的包,声明在源文件首行
- 包 package 属于标识符,遵循标识符的命名规范和原则
- 每一个 . 符号,就代表一层文件目录
补充: 同一个包下,不能够命名同名的接口、类(同一文件目录下不能有两个完全一样的文件)
image.png
import
image.png
image.png












网友评论