JAVA面向对象:封装性案例的实现

封装特性:

封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

优点:隐藏实现细节,提供公共的访问方式;

           提高了代码的复用性;

           提高了安全性。

封装原则:将不需要对外提供的内容都隐藏起来;

                  把属性隐藏,提供公共方法对其访问。

封装步骤:1.成员变量私有化;

                  2.提供对外访问的公共方法setter/getter方法。

注意:this用于当局部变量和成员变量重名时,使用this加以区分,this指代的是成员变量


模拟场景需求:

某校开设:“计算机科学与应用”专业,专业编号J0001,学制4年

现有3名学生都报名学习了这个专业:

姓名学号性别年龄
嘲风201621250725
晨曦201621250824
伊人201621251024

 

 

 

 


场景分析:

属性:学生 --> 姓名+性别+年龄+学号;     专业 --> 专业名称+专业编号+专业年限

对象:计算机科学与应用、嘲风、晨曦、伊人

类:学生类(嘲风、晨曦、伊人)、学科专业类(计算机科学与应用)

通过在两个类中实例化四个对象来完成具体场景的实现。

具体步骤:1.创建学生类、学科类;

                  2.建立类之间的联系;  ------------->  即在学生类中表现出他们是学这个专业的。

                  3.对新增需求的代码维护。


注意:对于私有属性赋值方法有两种
 一、是设置无参构造,通过设置setter方法来设置;
 二、是设置传参构造,直接通过构造方法赋值。


1.创建学生类与学科类:

public class Student {
	//成员属性:学号、姓名、性别、年龄
	private String name;
	private String idNum;
	private String sex;
	private int age;

	//无参构造
	public Student() {}
	
	//多参构造方法,实现对全部属性的赋值
	public Student(String name,String idNum,String sex,int age) {
		this.setName(name);
		this.setIdNum(idNum);
		this.setSex(sex);
		this.setAge(age);
		//this.age = age;这种方式没有对属性的逻辑限定,很容易出错。
	}
	
	//私有属性的getter、setter方法
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getIdNum() {
		return idNum;
	}
	public void setIdNum(String idNum) {
		this.idNum = idNum;
	}
	public String getSex() {
		return sex;
	}
	/**
	 * 限制性别只能是“男”或者“女”,反之则强制赋值为“男”
	 * @param sex 传入的年龄
	 * .equals()方法用于对比字符串的内容,相等则返回true。
	 * 已知字符串放于.equals方法前面,可以防止空指针异常。
	 */
	public void setSex(String sex) {
		if("男".equals(sex) || "女".equals(sex)) {
			this.sex = sex;
		}else {
			this.sex = "男";
		}
	}
	public int getAge() {
		return age;
	}
	/**
	 * 给年龄赋值,限定必须在10-80岁之间,反之赋值为18
	 * @param age 传入的年龄
	 */
	public void setAge(int age) {
		if(age>10 && age<80) {
			this.age = age;
		}else {
			this.age = 18;
		}	
	}
	
	/**
	 * 自我介绍的方法
	 * @return 学生的个人信息,包括:姓名、学号、性别、年龄
	 * 这种字符串的返回方式有利于提高代码的可扩展性,更适合多平台的展示。
	 */
	public String introduction() {
		String str = "学生信息如下:" + "\n姓名:" + this.getName()
					+ "\n性别:" + this.getSex() + "\n学号:" + this.getIdNum()
					+ "\n年龄:" + this.getAge();
		return str;
	}
}
public class Major {
	
	private String majorName;
	private String idNum;
	private int majorYear;
	
	//无参构造方法
	public Major() {}
	//有参构造方法
	public Major(String majorName,String idNum,int majorYear) {
		//一般使用setter方法进行属性赋值,因为这样可以利用setter方法内的逻辑判断提高安全系数
		this.majorName = majorName;
		this.setIdNum(idNum);
		this.setMajorYear(majorYear);
	}

	public String getMajorName() {
		return majorName;
	}

	public void setMajorName(String majorName) {
		this.majorName = majorName;
	}

	public String getIdNum() {
		return idNum;
	}

	public void setIdNum(String idNum) {
		this.idNum = idNum;
	}

	public int getMajorYear() {
		return majorYear;
	}
	
	//设置专业年限,设置数值必须大于1
	public void setMajorYear(int majorYear) {
		if(majorYear<=0) {
			return;
		}
		this.majorYear = majorYear;
	}
	
	/**
	 * 专业介绍的方法
	 * @return 专业的相关信息,包括专业名称、编号、年制
	 * 此处属性的调用可以使用getter方法,也可以直接使用属性名调用。但是当getter方法中有业务逻辑限制时,则必须使用getter方法;
	 * 返回字符串类型的对象,在外部输出时选择输出形式,有助于提高代码的复用性;同时也符合面向对象的单一职能原则,只考虑提供功能,而
	 * 不负责具体的展示功能。
	 */
	public String info() {
		String str = "专业信息如下:" + "\n专业名称:" + majorName + "\n专业编号:" + getIdNum() + "\n专业学制:" 
					+ getMajorYear();
		return str;
	}
}

2.建立类之间的联系: ---------------------   即在学生类中表现出他们是学这个专业的。

方案一:对学生类中自我介绍方法进行重载,传入学科名称、学制年限等参数。

注:在进行信息输出的时候,手动在方法中输入学科名称、学制年限等参数信息。

优点:容易理解

缺点:当输入信息过多时,会导致参数列表过长。

	/**
	 * 自我介绍的方法
	 * @return 学生的个人信息,包括:姓名、学号、性别、年龄
	 * 这种字符串的返回方式有利于提高代码的可扩展性,更适合多平台的展示。
	 */
	public String introduction() {
		String str = "学生信息如下:" + "\n姓名:" + this.getName()
					+ "\n性别:" + this.getSex() + "\n学号:" + this.getIdNum()
					+ "\n年龄:" + this.getAge();
		return str;
	}
	/**
	 * 学生自我介绍的方法
	 * @param majorName 所学专业名称
	 * @param majorYear 学制年限
	 * @return 自我介绍的信息,包括姓名、学号、性别、年龄、所学专业名称、学制年限。
	 */
	public String introduction(String majorName,int majorYear) {
		String str = "学生信息如下:" + "\n姓名:" + this.getName()
					+ "\n性别:" + this.getSex() + "\n学号:" + this.getIdNum()
					+ "\n年龄:" + this.getAge() + "\n所报专业名称:" + majorName 
					+ "\n学制年限:" + majorYear;
		return str;
	}

方案二:对学生类中自我介绍方法进行重载,在方法中添加1个专业对象作为参数,通过其属性获得相关信息。

注:这种方法能够通过对象获得类中的所有对象的属性特征。

优点:更加简单,在方法中只添加1个专业对象作为参数,通过对象的属性获得信息,获取参数也更方便。

缺点:关联性不是很强,只是因为用到了该方法,才需要专业的相关信息。

	//对introduction方法进行重载
	public String introduction(Major myMajor) {
		String str = "学生信息如下:" + "\n姓名:" + this.getName()
					+ "\n性别:" + this.getSex() + "\n学号:" + this.getIdNum()
					+ "\n年龄:" + this.getAge() + "\n所报专业名称:" + myMajor.getMajorName() 
					+ "\n学制年限:" + myMajor.getMajorYear() + "\n专业编号:" + myMajor.getIdNum();
		return str;
	}

方案三:在类中添加专业对象作为成员属性,通过其属性获得相关信息。

分析:作为一个大学生,他必须选择一个专业进行学习。因此可以添加专业信息作为学生类的成员属性存在。此时专业信息的类型即为Major,对于引用数据类型的默认值为null。(私有属性需要设置getter/setter方法)

注意:在调用 专业名称、专业学制 等学科类的属性时,需要先通过getter方法获得学生类的对象属性stuMajor,然后通过对象调用专业类中的属性。

优点:与方案二相比,关联性更强。专业已经成为学生的一个特征了。

	/**
	 * 自我介绍的方法
	 * @return 学生的个人信息,包括:姓名、学号、性别、年龄、专业名称、专业学制
	 * 这种字符串的返回方式有利于提高代码的可扩展性,更适合多平台的展示。
	 */
	public String introduction() {
		String str = "学生信息如下:" + "\n姓名:" + this.getName()
					+ "\n性别:" + this.getSex() + "\n学号:" + this.getIdNum()
					+ "\n年龄:" + this.getAge() + "\n专业名称:" + this.getStuMajor().getMajorName()
					+ "\n专业学制:" + this.getStuMajor().getMajorYear();
		return str;
	}

新增需求:

希望统计计算机科学与应用专业的报名学生人数。

新增需求分析:

1.在专业类中设置一个容器,将报名学生的信息都装进去;

2.遍历容器中学生的人数。

	public void addStudent(Student stu) {
		/**
		 * 1.将学生信息保存在数组中;
		 * 2.将学生个数保存在studentNum中。
		 */
		//1.将学生信息保存在数组中;
		for(int i=0 ; i<this.getMyStudents().length ; i++) {
			if(this.getMyStudents()[i] == null) {
				this.getMyStudents()[i] = stu;
				//2.将学生个数保存在studentNum中
				this.studentNum = i+1;
				return;
			}
		}
	}

====================================================================
	public void addStudent(Student stu) {
            int i;
		//1.将学生信息保存在数组中;
		for(i=0 ; i<this.getMyStudents().length ; i++) {
			if(this.getMyStudents()[i] == null) {
				this.getMyStudents()[i] = stu;
				break;
			}
		}
		//2.将学生个数保存在studentNum中
		this.studentNum = i+1;        
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值