封装学习与练习

本文探讨了面向对象编程中的封装原则,强调其作为保护屏障的重要性,通过类的封装可以隐藏内部细节,提高代码的可维护性和安全性。示例展示了如何在Java中实现封装,包括访问控制关键字的使用,以及如何通过get/set方法控制属性访问。同时,提供了两个实际案例,分别是 Citizen 类的设计和 MyArrays 工具类的实现,进一步说明封装在实际编程中的应用。
摘要由CSDN通过智能技术生成

封装

在面向对象程式设计方法中,封装 Encapsulation 是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
  • 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问
  1. 反射机制
  • 要访问该类的代码和数据,必须通过严格的接口控制。
  • 封装最主要的功能在于能修改自己的实现代码,而不用修改那些调用代码的程序片段
  • 适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。  
//第一步是确定研究的目标对象---可以区分的独立个体 
// 需要方法和属性 
class Student { 
    //成员属性---静态特征的描述 
    private boolean sex; //一般使用私有属性,共有的get/set方法 
    //成员方法---提供的功能描述 
    public boolean getSex(){ 
        return this.sex; 
    }
    //不允许修改sex,所以不提供set方法 
    protected void setSex(Boolean sex){ //如果在特殊情况下允许修改,可以使用范围限定词进行表示 
        this.sex=sex; 
    } 
}

//构建对象 
Student s1=new Student(); 
s1.setSex(true); 
s1.setSex(false); //是否允许取绝于限制

封装有三大好处

  • 良好的封装能够减少耦合
  • 类内部的结构可以自由修改
  • 可以对成员进行更精确的控制
  • 隐藏信息,实现细节 

4个关键字  

用于进行访问控制 

//一个文件种可以定义无数个类,但是只能有一个public class公共类 
public class Student { //类的范围限定词分为2种情况。外部类的范围限定词可以使用无范围 限定词和public两种;而内部类上可以使用4种范围限定 
    //成员属性,类种包含哪些静态特征取决于问题本身 
    private Long id; //private只能在当前类中直接访问 
    protected String name; //protected可以在同包或者子类中直接访问 
    int age;//没有范围限定词,默认或者package限定词,只能在同包中直接访问 
    public double salary;//public到处可见 


    //一般规则是私有属性,共有的get/set方法 
}

[点击并拖拽以移动]
​
记忆的方法
当前类内同包子类到处
privateT
无范围限定词TT
protectedTTT
publicTTTT

类定义规则:要求类内高内聚,类间弱耦合
  • 封装确实可以使容易地修改类的内部实现,而无需修改使用了该类的客户代码

练习 

案例:
声明公民类 Citizen ,包含属性:姓名,生日,身份证号,其中姓名是 String 类型,生日是 MyDate 类型身份证号也是 String 类型。
声明 T01 测试类,在 main 方法中创建你们家庭成员的几个对象,并打印信息。
public class MyDate {
  private int year, month, date;

  // 读取器,用于获取对象种的私有属性值
  public int getYear() {
    return year;
  }

  // 设置器,用于向对象种传入特定的属性值
  public void setYear(int year) {
    this.year = year;
  }

  public int getMonth() {
    return month;
  }

  public void setMonth(int month) {
    if (month > 0) {
    	if(month>12) {
      int y = month / 12;
      if (y > 0)
        year += y;
      month %= 12;
    	}
    } else {
      int y = month / 12 - 1;
      year += y;
      month = (-1 * y) * 12 + month;
    }
    this.month = month;
  }

  public int getDate() {
    return date;
  }


  public void setDate(int date) {
    if (date > 0) {
      while (true) {
        if (date > getMaxDate()) {
          date = date - getMaxDate();
          month++;
        }
        if (getMaxDate() >= date)
          break;
      }
    }
    this.date = date;
  }
  private int getMaxDate() {
	  int res = 0;
	  switch (month) {
	  case 1:
	  case 3:
	  case 5:
	  case 7:
	  case 8:
	  case 10:
	  case 12:
		  res = 31;
		  break;
	  case 4:
	  case 6:
	  case 9:
	  case 11:
		  res = 30;
		  break;
	  case 2:
		  if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
			  res = 29;
		  } else
			  res = 28;
		  break;
	  default:
		  res = 0;
		  break;
	  }
	  return res;
  }

  public String show() {
    return year + "年" + month + "月" + date + "日";
  }
}
public class Citizen {
	private String name;
	private MyDate birth;
	private String cardNo;
	
	public void show() {
		System.out.println("姓名:"+name+",生日:"+birth.show()+",身份证号:"+cardNo);
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public MyDate getBirth() {
		return birth;
	}
	public void setBirth(MyDate birth) {
		this.birth = birth;
	}
	public String getCardNo() {
		return cardNo;
	}
	public void setCardNo(String cardNo) {
		this.cardNo = cardNo;
	}

}
public class T01 {
	public static void main(String[] args) {
		Citizen[] cs = new Citizen[3];
		cs[0] = new Citizen();
		cs[0].setName("小黑");
		MyDate md1 = new MyDate();
		md1.setYear(2022);
		md1.setMonth(12);
		md1.setDate(20);
		cs[0].setBirth(md1);
		cs[0].setCardNo("610525199902152335");

		cs[1] = new Citizen();
		cs[1].setName("小白");
		MyDate md2 = new MyDate();
		md2.setYear(2021);
		md2.setMonth(6);
		md2.setDate(20);
		cs[1].setBirth(md2);
		cs[1].setCardNo("610525199902152335");

		for (int i = 0; i < cs.length; i++) {
			if (cs[i] != null)
				cs[i].show();

		}

	}
}
案例:
声明一个数组管理工具类 MyArrays ,包含如下方法:
1 void sort(int[] arr) :可以为任意一维整型数组 arr 实现从小到大排序
2 int indexOf(int[] arr, int value) :可以在任意一维整型数组 arr 中使用折半查找法查找 value 值的下
标,如果不存在返回 -1
3 int[] copy(int[] arr, int len) :可以实现从任意一维数组 arr 中复制一个新数组返回,新数组的长度为len ,从 arr[0] 开始复制
声明一个 Test07 测试类,并在 main 方法中调用测试
public class MyArrays {
	void sort(int[] arr) {
		for (int i = 1; i < arr.length; i++) {
			for (int k = 0; k < arr.length - i; k++) {
				if (arr[k] > arr[k + 1]) {
					int tmp = arr[k];
					arr[k] = arr[k + 1];
					arr[k + 1] = tmp;
				}
			}
		}
	}

	int indexOf(int[] arr, int value) {
		sort(arr);
		int index = -1;
		int min = 0;
		int max = arr.length - 1;
		while (min <= max) {
			int pos = (min + max) / 2;
			if (arr[pos] < value)
				min = pos + 1;
			else if (arr[pos] > value)
				max = pos - 1;
			else {
				index = pos;
				break;
			}
		}
		return index;
	}

	int[] copy(int[] arr, int len) {
		int[] res = new int[len];
		int c = 0;
		for (int k = 0; k < res.length; k++) {
			res[k] = arr[c++];
			c = c % arr.length;
		}
		return res;
	}

}
public class Test01 {
	public static void main(String[] args) {
		int[] arr = { 2, 3, 7, 5, 6, 1 };
		MyArrays ma = new MyArrays();

		ma.sort(arr);
		for (int b1 : arr)
			System.out.print(b1);
		int pos = ma.indexOf(arr, 5);
		System.out.println(pos);

		int[] brr = ma.copy(arr, 10);
		for (int tmp : brr)
			System.out.print(tmp + "\t");
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值