黑马程序员2.封装&构造函数&构造代码块&this关键字

-------android培训java培训java学习型技术博客、期待与您交流! ---------- 

今天看了毕老师第五天第二部分的内容,在这里总结一下。


1.封装

封装:是指隐藏对象的属性和实现细节,仅对外提供公共的访问方式。它的好处包括:1.将变化隔离2.便于使用3.提供重用性4.提高安全性。封装的原则是:将不需要对外提供的内容都隐藏起来,把属性都隐藏起来,提供公共方法对其访问。举个例子,小张要买电脑,但是不懂行,找老李帮忙,小张只管拿到电脑,至于老李是怎么参考资料,咨询,砍价的,他没有必要知道。在程序中,这些方法就称为透明的或者隐藏的。函数本身是最小的封装体。对于类来说,它可以选择将一些方法隐藏起来,而将另外一些方法暴露给别人。


2.如何进行封装

class Person
{
int age;
void speak();
{
System.out.println("age="+age);
}
}
class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person();
p.setAge(-40);
}
}

 这里p.age= -20 会带来安全隐患,这是age被直接访问带来的。可以将age进行封装,并对外提供访问方式: 

class Person
{
private int age;
public void setAge(int a)
{
age = a;
}
public int getAge()
{
return age;
}
void speak()
{
System.out.println("age="+age);
}
}

 通过p.setAge(20); 将20赋给age。一个成员变量通常都有两个访问方式,设置和获取。这样age这个成员变量就被封装到Person类里面了。但是, 
私有仅仅是封装的一种表现形式。不私有也可以实现封装,只要权限是你访问不到的,对于你来说就是封装的。但是现在还是可以将-20赋给age,那么,封装的意义有是什么?我们将属性私有是为了不让外部访问,我们提供访问方式给外部,是因为我们可以在访问方式中加入逻辑判断等语句。对访问的数据进行操作,提高代码的健壮性。所以代码可变为: 

public void setAge(int a)
{
if(a>0 && a<130)
{
age = a;
speak();
}
else 
System.out.println("非法age");
}

另外,成员变量和局部变量的区别还包括:成员变量有默认值初始化值,不赋值也可以直接参与运算,因为它在堆内存中,而局部变量不行,因为它在栈内存中,必须有初始化值才能参与运算。见下图:


当程序执行到p.setAge(40)时,a的值将赋给new Person()这个对象中的age.注意,class Person中的private int age成员变量并没有被赋值,而且setAge()方法也没有指向这个new Person()对象,它只是把a赋给了这个对象中的age.


3.构造函数

特点:1.函数名和类名相同2.不用定义返回值类型3.不用写return语句。作用:给对象初始化。注意:1.默认构造函数的特点。2.多个构造函数是以重载的形式存在的。

class Person
{
Person()
{
System.out.println("Person run");
}
}

class PersonDemo2
{
public static void main(String[] args)
{
Person p =new Person();
}
}

从执行结果可以看到,对象一建立,构造函数就被执行了。构造函数可以用于给对象进行初始化。

构造函数的小细节:当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。当在类中自定义了构造函数后,默认的构造函数就没有了。

一个类中可以写多个构造函数。构造函数具备重载特性。重载就是函数名相同,但是参数列表不同。代码如下:

class Person
{
private String name;
private int age;
Person()
{
System.out.println("A: name="+name+“,,age=”+age);
cry();
}
Person(String n)
{
name = n;
System.out.println("B: name="+name+“,,age=”+age);
cry();
} 
Person(String n, int a)
{
name = n;
age = a;
System.out.println("C: name="+name+“,,age=”+age);
cry();
}
public void cry()
{
System.out.println("cry........................");
}
}

构造函数和一般函数在写法上有不同,在运行上也有不同,构造函数是在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,是给对象添加对象具备的功能。一个对象建立,构造函数只运行一次。而一般方法可以被该对象调用多次。

什么时候定义构造函数呢?当分析事物时,该事物存在具备一些特性或者行为,那么就将这些内容定义在构造函数中。构造函数如果在定义时需要位置内容参与运算,需要就定义参数。


4.构造代码块

class Person
{
private String name;
private int age;
{
System.out.println("person code run");
}
Person()
{
System.out.println("A: name="+name+“,,age=”+age);
cry();
}
}

红字内容为构造代码快,它的作用是,给对象进行初始化,对象一建立就运行,而且优先于构造函数执行。

和构造函数的区别:构造代码快是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。构造代码块中定义的是不同对象共性的初始化内容。

构造函数是可以被private修饰的,因为private是用来修饰成员的(成员变量,成员函数)。但是这对象就不能进行初始化,如果把类中的所有构造函数都声明成private的话,这个类的对象就不可能被建立,因为不能初始化。


5.this 关键字

Person(String name)
{
name = name;
System.out.println("B: name="+name+“,,age=”+age);
cry();
} 

通过运行,我们发现,Person p = new Person("LiSi"); 执行后打印的name为null,这证明name没有被赋给对象中的name成员变量。我们发现以上代码中,构造函数中的局部变量和类中的成员变量名字重复了,都叫name。这说明构造函数中的name就是局部变量的那个name而不是成员变量的那个name。局部中有就用局部的,没有再到成员中去找。this:看上去是用于区分局部变量和成员变量同名的情况。代码如下:

Person(String name)
{
this.name = name;
System.out.println("B: name="+name+“,,age=”+age);
cry();
} 

this为什么可以解决这个问题?this到底代表的是什么?

this代表本类的对象。this代表它所在函数所属对象的引用。简单说,哪个对象在调用this所在的函数,this就代表哪个对象。而在类中,成员之间的互相调用实际上是对象完成的,比方说speak()的代码实际上是:

public void speak()

{

System.out.println("name="+this.name+"...age="+this.age);

this.show();

}

public void show()

{

System.out.println(this.name);}

它实际上使用对象来区分到底打印的是哪个对象的成员。而show()方法打印的name和speak()是一样的。这是因为函数是被对象调用的,speak()调用的时候,省略了this.。

this的应用:当定义类中的功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。但凡本类功能内部使用到了本类对象,都用this表示。

this应用举例:

class Person

{

private String name;

private int age;

Person(int age)

{

this.age = age;

}

Person(String name, int age)

{

this.name = name;

this.age = age;

}

public void speak()

{

System.out.println("name="+this.name+"...age="+this.age);

this.show();

}

public void show()

{

System.out.println(this.name);

}

public boolean compare(Person p)

{

return this.age==p.age;

}

}


class PersonDemo3

{

public static void main(String[] args)

{

Person p1 = new Person(20);

Person p2 = new Person(25);

boolean b = p1.compare(p2);//此时, compare方法中的this和p1的地址值是一样的,他们指向了同一个对象。

System.out.println(b);

}

}


this关键字在构造函数间的调用

this语句:用于构造函数之间进行互相调用。构造函数间调用只能用this语句。

class Person

{

private String name;

private int age;

Person(String name)

{

this.name = name;

}

Person(String name, int age)

{

this(name);//代表Person(name)构造函数,构造函数与一般函数不同,不能直接写成Person(name);来调用,现在代表p(name)

this.age = age;

}

class PersonDemo4

{

public static void main(String[] args)

{

Person p = new Person("LiSi", 30);

}

}

this语句只能定义在构造函数的第一行,初始化的动作要先执行,如果初始化中还有初始化,就先执行初始化中的初始化。

Person(String name)

{

this.name = "haha";

}

Person(String name, int age)

{

this.name = name;//lisi已经赋值给了对象的name

this(name);//调用的时候把name给改成haha了

this.age = age;

}


------- android培训 java培训 java学习型技术博客、 期待与您交流! ---------- 


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值