文章目录
今日提要:封装(其实说白了,封装就是对访问范围的限制,不用因为名字就觉得高大上了)哦,对了,还要顺便讲个构造函数
我在两天的学习里都提到了封装,而且是很严肃的,那你就应该知道这个封装对于Java程序非常重要;
把昨天最后一个狗狗的程序拿过来用作例子吧
1.封装
public class BeginnerTestDog {//创建一个公共类
public static void main(String[] args) {//main()函数
//依据DogClass创建一个名为one的对象
DogClass one = new DogClass();
one.size = 15;//身长
one.weight = 3;//体重
one.breed = "泰迪";//品种
one.name = "黑漆漆";//名字
one.dogReaction();//调用方法
//依据DogClass创建一个名为two的对象
DogClass two = new DogClass();
two.size = 80;
two.weight = 60;
two.breed = "金毛";
two.name = "老牛牛";
two.dogReaction();
}//end main
}//end class
class DogClass{
int size;//身长
int weight;//体重
String breed;//品种
String name;//名字
void dogReaction() {
String bark = "汪汪汪";
//判断狗的叫声
if (weight <= 5) {
bark = "歪歪歪";
}else if(weight > 5 && weight <= 15) {
bark = "汪汪汪";
}else if(weight > 15 && weight <= 30) {
bark = "汪呜汪呜汪呜";
}else if(weight > 30) {
bark = "嗡呜嗡呜嗡呜";
}//end if
//输出结果
System.out.println("一只身长 " + size + " 公分,体重 " + weight + " 公斤,名叫 " + name +" 的 "+ breed + " 正在 " + bark + " 的叫着");
}//end dogReaction
}//end DogClass
大家可以看得很清楚,上面这个程序我在公共类里为DogClass类的实例变量直接进行了赋值,这仅是为了大家便于观察实例变量和对象的依存关系,首先说明这样的做法对于一个Java程序而言风险极大,应该是重点避免的,一个安全的Java程序,应该做到,类内数据操作的细节,自主完成,不接受外部干涉,外部仅能调用和操作对外开放的方法,禁止一切对对象数据实际表示的访问,应通过方法进行操作和访问。
以上加粗字体翻译成人话就是:类内数据必须设置访问权限,不允许外部直接操作,想要操作必须通过方法进行;
这里涉及到的最重要的原则:变量作用域最小原则;
让我们更改一下上面的狗狗程序,来看看不同之处
public class BeginnerTestDog {//创建一个公共类
public static void main(String[] args) {//main()函数
//依据DogClass创建一个名为one的对象
DogClass one = new DogClass(15, 3, "泰迪", "黑漆漆");
//one.DogClass(15, 3, "泰迪", "黑漆漆");
//one.size = 15;//身长
//one.weight = 3;//体重
//one.breed = "泰迪";//品种
//one.name = "黑漆漆";//名字
one.dogReaction();//调用方法
//依据DogClass创建一个名为two的对象
DogClass two = new DogClass(80, 60, "金毛", "老牛牛");
//two.DogClass(80, 60, "金毛", "老牛牛");
//two.size = 80;
//two.weight = 60;
//two.breed = "金毛";
//two.name = "老牛牛";
two.dogReaction();
}//end main
}//end class
class DogClass{
private int size;//身长
private int weight;//体重
private String breed;//品种
private String name;//名字
DogClass (int tempSize, int tempWeight, String tempBreed, String tempName) {//设置一个构造函数,初始化变量
size = tempSize;
weight = tempWeight;
breed = tempBreed;
name = tempName;
}// end 构造函数
void dogReaction() {
String bark = "汪汪汪";
//判断狗的叫声
if (weight <= 5) {
bark = "歪歪歪";
}else if(weight > 5 && weight <= 15) {
bark = "汪汪汪";
}else if(weight > 15 && weight <= 30) {
bark = "汪呜汪呜汪呜";
}else if(weight > 30) {
bark = "嗡呜嗡呜嗡呜";
}//end if
//输出结果
System.out.println("一只身长 " + size + " 公分,体重 " + weight + " 公斤,名叫 " + name +" 的 "+ breed + " 正在 " + bark + " 的叫着");
}//end dogReaction
}//end DogClass
看到这里会发现,在实例变量的前面多了一个修饰符“private”,这就是一个访问权限修饰符,这样的修饰符我们共有四个
**“public”、“protected”、“默认空修饰符”、“private”**它们的可见范围是依次缩小的,“public”(公共)最大,谁都能访问,“private”(私有)最小,只有本类可以访问,作为初学者的我们应习惯将实例变量的访问权限设置为“private”,这样能最好的保护类的结构和输出结果不被破坏。
就比如说,如果不控制访问权限范围,而某个类里书写了,“xx.size = 0;”,那么我们将得到一个没有厚度的二维的狗狗(二向箔么?)或者书写了“xx.weight = -20”;那么我们就得到了一个失重的狗狗,不过也好,能飞了,作为一个正常逻辑的程序,这些结果都不是我们想要的,也不是我们书写的初衷,那么设置访问权限私有,就很好的解决了这个问题,你看了眼程序,翻了一个白眼说,我还不是一样能把参数设置成0,有什么区别?那就来说说区别
DogClass (int tempSize, int tempWeight, String tempBreed, String tempName) {//设置一个构造函数,初始化变量
if (tempSize > 8 && tempSize < 120) {//设定狗狗身长的范围
size = tempSize;
}else {
System.out.println("你输入的尺寸不符合要求,按照默认值输出");
size = 9;
}//end if
weight = tempWeight;
breed = tempBreed;
name = tempName;
}// end 构造函数
看到区别了么?(我耸了耸肩,对你一笑,摊开手说)你的二向箔狗狗没有了…同理也可以让失重的狗狗消失(飞走了不是消失,飞到哪里,都是客观实在,只不过有可能看不到了而已,这是有区别的)。
这就是我们现阶段需要了解的封装,以后经验丰富了,或许会根据不同的需求,可以采取不同访问权限的设置,但是私有始终是最安全的。
2.变量的作用域
方法内声明并赋值的变量,作用域只在这个方法内
void test01() {
int i = 10;
System.out.println(i);
}
void test02() {
int i = 100;
System.out.println(i);
}
也就是说test01()方法,和test02()方法里面声明和赋值的 i 变量,并没有直接的关系,它们有各自的作用域,也就声明它们的方法内;
还有就是循环语句:for(int a = 0;…){}这里的变量 a 作用域仅限这个for后面的{…}中;
上面所说的变量 i 和变量 a ,都是作用在一个局部的变量,也称局部变量,这里要注意一个问题,局部变量没有默认值,声明的局部变量,必须进行赋值,必须!!!!
3.构造函数
构造函数?是不是不好理解?那我换个名字,构造方法,是个方法哦
DogClass (int tempSize, int tempWeight, String tempBreed, String tempName) {//设置一个构造函数,初始化变量
size = tempSize;
weight = tempWeight;
breed = tempBreed;
name = tempName;
}// end 构造函数
这是一个特殊的方法,它是用来初始化类内实例变量的,其实每个类在被对象调用的时候,都会执行一个构造函数,只不过如果我们不写的话,它就执行默认的构造方法,完成实例变量的初值设置,但如果我们写了构造函数,那么在编译的时候,就不会再执行默认的构造函数了,转而优先执行我们写的构造函数;
构造函数的几个特征:
- 构造函数的名称与类的名称完全相同。
- 构造函数没有返回类型,包括void。
- 构造函数在创建对象时被自动调用。
- 构造函数在对象实例化时用来初始化对象的成员。
- 构造函数可以有参数,也可以没有参数。
- 构造函数可以重载,即可以有多个同名但参数列表不同的构造函数。
有以上特征的方法,就是一个构造函数,这里有个需要例子说明的,我们来看下例句:
class TestA{
TestA (int a,String b){
}
TestA(){
}
}
大家可能发现了,这个类里面有两个构造函数,只不过一个有参数,一个没有参数,这是合法的,当然你还可以书写其他参数列表不同的同名构造函数,就要看你程序的需要了;
那我们创建对象的时候又有什么不同呢?
TestA a = new TestA();//调用的无参构造函数初始化对象
TestA a1 = new TestA(10,"参数");//调用有参构造函数初始化对象
一般来说,有参方法的参数输入到方法后面的()中,但是构造函数不同,因为它的作用是初始化对象,所以它的参数会出现在创建对象的时候,输入到类名后面的括号内,这就是构建函数与普通方法的不同之处之一;
上面这两个语句就是所谓的构造函数重载,大家知道怎么回事,知道如何书写就好,至于运用的话,只能在实战中不断深化的。
标签:JAVA,weight,DogClass,第八天,int,two,String,日志,构造函数 From: https://blog.csdn.net/mycqyjn/article/details/140191560