一、封装的概述
1.定义一个学生类:
成员变量:name,age;
成员方法:show()方法。
我们在使用这个案例的过程中发现了一个问题。
通过对象去给成员变量赋值,可以赋值一些非法的数据。
这是不合理的。
应该是这个样子的,在赋值之前,先对数据进行判断。
判断到底在哪里做比较合适呢?
StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。
所以,这个判断应该定义在Student类中。
而我们在成员变量的位置可不可以进行 数据判断呢?
是不可以的,因为做数据校验必须要依靠一些逻辑语句。
逻辑语句是应该定义在方法中,所以,我们最终决定在Student类中提供一个方法
按照我们前面的分析,我们给出了一个方法进行校验
但是呢,它偏偏不调用方法来赋值,还是直接赋值了,
这样我们的方法就没有起到作用。
我就应该要求你必须使用我的方法,而不能直接调用成员变量赋值。
怎么去强制要求不能直接使用成员变量呢?
针对这种情况,java就提供了一个关键字private
private:私有的,可以修饰成员变量和成员方法。
注意:被private修饰的成员只能在本类中访问。
其实讲到现在讲解的是一个封装的思想。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
class Student{
//姓名
String name;
//年龄
private int age;
//写一个方法对数据进行校验
/*
返回值类型:void
参数列表:int a
*/
public void setAge(int a){
if(a < 0 || a > 120){
System.out.println("年龄有问题!");
}else{
age = a;
}
}
//show()方法,显示所有成员变量值
public void show(){
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
}
}
class StudentDemo{
public static void main(String[] args){
Student s = new Student();
s.show();
System.out.println("-----------");
s.name = "XXX";
//s.age = 20;
s.setAge(20);
s.show();
System.out.println("-----------");
//给age赋值
//s.age = -21;//这个数据是不合理的。
s.setAge(-20);
s.show();
System.out.println("-----------");
}
}
2.封装的好处:
隐藏实现细节,提供公共的访问方式
提高了代码的复用性。
提高了安全性。
封装的原则:
把不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问。
3.private的特点
记住:凡是不需要被外界访问的成员,都可以设置成private
private:
是一个权限修饰符
可以修饰成员变量和成员方法,外界不能直接访问
被其修饰的成员只能在本类中被访问。
class Demo{
//int num = 10;
//用private修饰
private int num = 10;
public void show(){
System.out.println(num);
}
private void method(){
System.out.println("method");
}//如果想要在外界直接调用这个方法,是调用不了的,
//需要向外界提供一个公共的访问窗口
public void function(){
method();
}
}
class PrivateDemo{
public static void main(String[] args){
Demo d = new Demo();
//System.out.println(d.num);
d.show();
//不能访问私有的成员方法
//d.method();//错误: method()可以在Demo中访问private
d.function();
}
}
4.private的应用
封装和private的应用
A:把成员变量用private修饰
B:提高对应的getxxx()和setxxx()方法。
**对外提供一个给成员变量赋值和获取值的方法。
class Student{
//姓名
private String name;
//年龄
private int age;
//给姓名赋值
public void setName(String n){
name = n;
}
//获取姓名值
public String getName(){
return name;
}
//给年龄赋值
public void setAge(int a){
age = a;
}
//获取年龄的值
public int getAge(){
return age;
}
}
//测试类
class PrivateDemo2{
public static void main(String[] args){
//创建学生对象
Student s = new Student();
//使用成员变量
//错误:被私有修饰了,外界不能直接访问了。
//System.out.println(s.name+"---"+s.age);
System.out.println(s.getName()+"----"+s.getAge());
//给成员变量赋值
//通过方法赋值
s.setName("XXX");
s.setAge(27);
System.out.println(s.getName()+"----"+s.getAge());
}
}
标准类的代码是不需要做数据校验的,数据校验可以放在浏览器中来校验。
二、this关键字的概述和应用
起名字要做到见名知义。
this:是当前类的对象引用。简单的记,它就代表当前类的一个对象。
注意:谁调用这个方法,在该方法内部的this就代表谁。
this的场景:
解决局部变量隐藏成员变量
class Student{
//姓名
private String name;
//年龄
private int age;
//给姓名赋值
public void setName(String name){
// name = name;//变量的使用规则:就近原则。
//这里是类名,目前还没有说过类似的用法,所以这个是有问题的。
//这里的调用只能通过对象名
//这个对象如果存在,它应该代表的是Student的一个对象
//那么,谁能够代表当前类的对象呢?java提供了一个关键字:this
this.name = name;
}
//获取姓名值
public String getName(){
return name;
}
//给年龄赋值
public void setAge(int age){
this.age = age;
}
//获取年龄的值
public int getAge(){
return age;
}
}
class ThisDemo{
public static void main(String[] args){
//创建学生对象
Student s = new Student();
s.setName("XXX");
s.setAge(21);
System.out.println(s.getName()+"----"+s.getAge());
}
}
this:哪个对象调用那个方法,this就代表那个谁
class Student{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;//这里其实是隐含了this
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
class StudentDemo{
public static void main(String[] args){
//创建一个对象
Student s = new Student();
s.setName("周秀蓉");
s.setAge(27);
System.out.println(s.getName()+"----"+s.getAge());
//创建第二个对象
Student ss = new Student();
ss.setName("杨斌");
ss.setAge(30);
System.out.println(ss.getName()+"----"+ss.getAge());
}
}
标准手机类及其测试
手机类:
成员变量:
品牌
价格
颜色
成员方法:
针对每一个成员变量给出对应的getxxx()方法和setxxx()方法
最后定义测试:
创建一个对象,先通过getxxx()方法输出成员变量的值。
这一次的结果是:null—0—null
然后通过setxxx()方法给成员变量赋值。再次输出结果。这一次的结果是:
三星—3999—土豪金
class Phone{
//品牌
private String brand;
//价格
private int price;
//颜色
private String color;
//getxxx()和setxxx()方法
public void setBrand(String brand){
this.brand = brand;
}
public String getBrand(){
return brand;
}
public void setPrice(int price){
this.price = price;
}
public int getPrice(){
return price;
}
public void setColor(String color){
this.color = color;
}
public String getColor(){
return color;
}
}
class PhoneTest{
public static void main(String[] args){
//创建手机对象
Phone p = new Phone();
//直接输出默认值
System.out.println(p.getBrand()+"----"+p.getPrice()+"----"+p.getColor());
//给成员变量赋值
p.setBrand("三星");
p.setPrice(3999);
p.setColor("土豪金");
//再次输出
System.out.println(p.getBrand()+"----"+p.getPrice()+"----"+p.getColor());
}
}
三、构造方法
1.给对象的数据进行初始化
格式:
A:方法名与类名相同
B:方法没有返回值类型,连void都没有
C:没有具体的返回值。
class Student{
private String name;//null
private int age;//0
public Student(){
System.out.println("这是构造方法!");
}
}
class ConstructDemo{
public static void main(String[] args){
//创建对象
Student s = new Student();
System.out.println(s);//Student@77ec3adc
}
}
2.我们一直在使用构造方法,但是,我们确没有定义构造方法,用的是哪里来得呢?
构造方法的注意事项:
A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
给成员变量赋值有两种方式:
A:setxxx()方法
B:构造方法
class Student{
private String name;
private int age;
public Student(){
System.out.println("我给了无参构造方法,你还给不?");
}
//构造方法的重载格式
public Student(String name){
System.out.println("这是一个带String类型的构造方法");
this.name = name;
}
public Student(int age){
System.out.println("这是一个带int类型的构造方法");
this.age = age;
}
public Student(String name, int age){
System.out.println("这是一个带多个类型的构造方法");
this.name = name;
this.age = age;
}
//向外提供一个公共的方法。
public void show(){
System.out.println(name+"-----"+age);
}
}
class ConstructDemo2{
public static void main(String[] args){
//创建对象
Student s = new Student();
System.out.println("---------");
//创建对象2
Student s2 = new Student("XXX");
s2.show();
//创建对象3
Student s3 = new Student(21);
s3.show();
//创建对象4
Student s4 = new Student("XXX",21);
s4.show();
}
}
四、成员方法以及构造方法
类的组成:成员变量,成员方法
今天我们又加入了一个新的成员:构造方法
以后类的组成:
成员变量
构造方法
成员方法
根据返回值:
void类型
非void类型
根据形式参数:
空参方法
非空参方法
class Student{
//带明确返回值的
public String getString(){
return "hello";
}
//没有返回值的,void类型
public void show(){
System.out.println("show");
}
//带参数没有返回值
public void method(String name){
System.out.println(name);
}
//带参数有返回值
public String function(String s1, String s2){
return s1+s2;
}
}
class StudentDemo{
public static void main(String[] args){
//创建对象
Student s = new Student();
//调用无返回值类型方法
s.show();
//调用有返回值类型方法
String result = s.getString();
System.out.println(result);
//调用带参无返回值类型的方法
s.method("XXX");
//调用带参数有返回值类型的方法
String result2 = s.function("XXX","和YYY");
System.out.println(result2);
}
}
五、创建对象做了哪些事情
六、什么时候定义成员变量
定义一个类Demo,其中定义一个求两个数据和的方法,
定义一个测试类Test,进行测试。
变量什么时候定义成成员变量:
如果这个变量是用来描述这个类的信息的,那么,
该变量就应该定义为成员变量
变量到底定义在哪里好呢?
变量的范围是越小越好,因为能及时的被回收。