Loading

深度分析类与对象

2.0 深度分析类与对象

2.1 成员属性封装

​ 在类之中的组成就是属性与方法,一般而言方法都是对外提供服务的,所以是不会进行封装处理的,而对于属性由于其需要较高的安全性,所以往往需要对其进行保护,这个时候就需要采用封装性对属性进行保护。
​ 在默认的情况下,对于类中的属性是可以通过其他类利用对象进行调用。

范例:属性不封装情况下的问题

class Person {	//定义一个类
	String name; 	//人员的姓名
	int age;	//人的年龄
	public void tell() {
		System.out.print("姓名:" + name + "、年龄:"  +  age);
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		Person per = new Person(); //声明并实例化对象
		per.name = "张三"; //在类外部修改属性
		per.age = -18; //在类外部修改属性
		per.tell(); //进行方法的调用
	}

}

​ 此时在Person类中提供的name与age两个属性并没有进行封装处理,这样外部就可以直接进行调用了,但是有可能所设置的数据是错误的。如果要解决这样的问题就可以利用private关键字对属性进行封装处理。

范例:对属性进行封装

class Person {	//定义一个类
	private String name; 	//人员的姓名
	private int age;	//人的年龄
	public void tell() {
		System.out.print("姓名:" + name + "、年龄:"  +  age);
	}
}

​ 而属性一旦封装之后外部将不能够置界访问,即:对外部不可见,但是对类内部是可见的,那么如果要让外部的程序可以访问封装的属性,则在Java开发标准中提供有如下要求:

  • 【setter、getter】设置或取得属性可以使用setXxx()、getXxx()方法,以private String name为例:

    ​ |-设置属性方法:public void setName(String n);

    ​ |-获取属性方法:public String getName()。

范例:实现封装

class Person {	//定义一个类
	private String name; 	//人员的姓名
	private int age;	//人的年龄
	public void tell() {
		System.out.print("姓名:" + name + "、年龄:"  +  age);
	}
	public void setNmae(String n) {
		name = n;
	}
	public void setAge(int a) {
		if(a >= 0){
			age = a;
		}
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		Person per = new Person(); //声明并实例化对象
		per.setNmae("张三");
		per.setAge(-18);
		per.tell(); //进行方法的调用
	}

}

在以后进行任何类定义的时候一定要记住,类中的所有属性都必须使用private封装,并且属性如果要进行访问必须要提供有setter、getter方法。

2.2 构造方法与匿名对象

现在的程序在使用类的时候一般都按照了如下步骤进行:

  • 声明并实例化对象,这时候实例化对象中的属性并没有任何的数据存在,都是其对应数据类型的默认值
  • 需要通过一系列的setter方法为类中的属性设置内容

但是如果按照这样的方式进行思考的话就会发现一个问题:假设说现在类中的属性很多个(8个),那么这样一来按照之前的做法,此时就需要调用8此的setter方法进行内容设置,这样的调用实在太啰嗦了,所以在Java里面为了考虑到对象初始化的问题,专门提供有构造方法,即:可以通过构造方法实例化对象中的属性进行初始化处理。只有在关键字new的时候使用构造方法,在Java程序里面构造方法的定义要求如下:

  • 构造方法名称必须与类名称保持一致
  • 构造方法不允许设置任何的返回值类型,即:没有返回值定义
  • 构造方法是在使用关键字new实例化对象的时候自动调用的

范例:定义构造方法

class Person {	//定义一个类
	private String name; 	//人员的姓名
	private int age;	//人的年龄
	public Person(String n, int a) {
		name = n;
		age = a;
	}
	public void tell() {
		System.out.print("姓名:" + name + "、年龄:"  +  age);
	}

}
public class JavaDemo {
	public static void main(String args[]) {
		Person per = new Person("张三",18); //声明并实例化对象
		per.tell(); //进行方法的调用
	}

}

下面怎会当前对象实例化格式与之前的对象实例化格式做一个比较:

  • 之间的对象实例化格式:①Person ②per = ③new ④Person();

  • 当前的对象实例化格式:①Person ②per = ③new ④Person(“张三”,18);

    ​ |- “①Person”:主要是定义对象的所属类型,类型决定了你可以调用的方法

    ​ |- “②pe'r”:实例化对象的名称,对所有的操作通过对象来进行访问;

    ​ |- “③new”:开辟一块新的堆内存空间

    ​ |- “④Person("张三",18)“:调用有参构造、④”Person()“:调用无参构造

在Java程序里面考虑到程序结构的完整性,所以所有的类都会提供有构造方法,也就是说如果现在你的类中没有任何构造方法,程序会提供有一个无参的,什么都不做的构造方法,这个构造方法实在程序编译的时候自动创建的。

疑问:

​ 为什么构造方法上不允许设置返回值类型?
​ 构造方法是一个方法,那么为什么不让它定义返回值类型呢?
​ 既然构造方法不返回数据,为什么不适用void定义呢?

分析:

​ 程序编译器是根据代码结构来进行编译处理的,执行的时候也是根据代码结构来处理的.如果在构造方法上使用了void,那么此结构就与普通方法的结构完全相同。这样编译器会认为此方法是一个普通方法。普通方法与构造方法最大的区别:构造方法实在类对象实例化的时候调用的,而普通方法是在类对象实例化产生之后调用的

范例:构造方法重载

class Person {	//定义一个类
	private String name; 	//人员的姓名
	private int age;	//人的年龄
	public Person() {
		name = "无名氏";
		age = -1;
	}
	public Person(String n) {
		name = n;
	}
	public Person(String n, int a) {
		name = n;
		age = a;
	}
	public void tell() {
		System.out.print("姓名:" + name + "、年龄:"  +  age);
	}

}
public class JavaDemo {
	public static void main(String args[]) {
		Person per = new Person(); //声明并实例化对象
		per.tell(); //进行方法的调用
	}

}

经过分析可以发现,构造方法的确是可以进行数据的设置,而对于setter也可以进行数据的设置,这个时候一定要清楚,构造方法是在对象实例化的时候为属性设置初始化内容,而setter除了拥有设置数据的功能之外,还具有修改数据的功能。

如果只是通过实例化对象来进行类的操作也是可以的,而这种形式的对象,由于没有名字就成为匿名对象

范例:观察匿名对象

public class JavaDemo {
	public static void main(String args[]) {
		new Person("张三",10).tell();
	}
}
posted @ 2021-02-25 11:21  北络  阅读(53)  评论(0编辑  收藏  举报