面向对象的语言都有一些特征:继承、封装、多态、组合
注意哦,这里,千万不要写成Java的三大特征(错误的哈)
我们今天来认识的是封装!!!
开始嘞,咱们来举一个例子
我们写代码会涉及两种角色:类的实现者和类的调用者,代码整起!!
代码示例1:
class Student{
public String myName;
public int age;
public void show(){
System.out.println("姓名"+myName+"年龄"+age);
}
}
public class TestDemo2 {
public static void main(String[] args) {
Student student = new Student();
student.myName= "bit";
System.out.println(student.myName);
}
}
代码示例2:
class Student{
public String name;
public int age;
public void show(){
System.out.println("姓名"+myName+"年龄"+age);
}
}
public class TestDemo2 {
public static void main(String[] args) {
Student student = new Student();
student.myName= "bit";
System.out.println(student.myName);
}
}
仔细观察下上面两个代码的区别,发现了什么?类的实现者一旦将类里面的成员属性名字改了(myName---->name),类的调用者必须返回去将对应的myName变成name。这样的话,大大增加了使用者的学习和使用成本,很麻烦是不是?
封装的本质呢就是让类的调用者不必太多的了解类的实现者是如何实现类的,只要知道如何使用类就行了,哈哈哈哈哈,是不是觉得封装很有用呐oo(^ - ^)oo
如何实现封装?
- 用private关键字修饰成员
- private是私有的,被其修饰之后,只能在当前类中使用
- 每个类都会预留公有的接口的,一旦你把这个方法设置为public,那么就不要轻易修改他的属性为其他属性。
- 降低类的调用者的学习成本,同时也为了给好滴管理我们的代码,会提高开发效率。
- 提供一系列的get和set方法
代码示例:
class Student{
private String myName;
public String getMyName(){
return myName;
}
public void setMyName(String name){
myName = name;
}
}
public class TestDemo2 {
public static void main(String[] args) {
Student student = new Student();
student.setMyName("YaRu");
System.out.println(student.getMyName());
}
}
不过嘞,上面那个程序要注意一点哦
public void setMyName(String myName){
myName = myName;
}
这个代码会出错,myName本是一个局部变量,在花括号内有效,但是,局部变量优先,相当于形参给自己赋值,没有任何作用,是一个null
不过嘞,前面加一个this,就会有不一样的效果
public void setMyName(String myName){
this.myName = myName;
}
this是什么呐?很多书,包括博客都说this代表当前对象,有点不太准确,准确来说,代表的是当前对象的引用 指明是对当前对象myName的引用,this.myName中的myName是成员变量
不过,如果有多个成员变量,get和set方法一个一个敲上去,啊~~,那也太麻烦了吧,不过嘞,咱们有快捷键,Alt+Inset即可(按住shift键,可以同时选中好多个成员变量)
为什么有this?
public void show(){
System.out.println("姓名"+this.myName+"年龄"+this.age);
}
习惯使用this关键字,因为代码多了,重复不重复自己也不知道,咱们代码不怕长,只要合理就好
如何自动生成可以打印属性的方法:按住Alt+Inset键,会出现好多选项,选择toString(),选择自己想要打印的选项就可以了哦!具体长啥样呢,look look下面的代码示例
@Override//注解:代表当前方法是重写的
public String toString() {
return "Student{" +
"myName='" + myName + '\'' +
", age=" + age +
'}';
}
System.out.println(student);//这一句位于主函数内
结果:
Student{myName='bit', age=0}
不过这个代码块是怎么用的呢?咱们先来看看下一句,运行一下的结果:
System.out.println(student);
结果:
Student@1b6d3586
@前面的Student是当前引用的类型,@后面的一串是当前引用类型的哈希值(堆上的地址的哈希的值)
当执行只一句代码的时候,会调用底层的Object的toString()方法,如果自己通过按住Alt+Inset键,选择toString(),则接下来会执行自己的toString()方法,具体请看图详解
所有的get set 和 toString都可以通过快捷键来实现。
构造方法
回顾一下,什么是方法呢?方法是由方法的返回值,方法的名称,方法的参数列表,方法体构成。
什么是构造方法呢?
没有返回值且方法名和类名是一样的。
一个对象的产生,需要分为几步?
- 为对象分配内存
- 调用合适的构造方法(什么叫合适的?构造方法不止一个)
代码示例:
class Student{
private String myName;
private int age;
public Student(){
System.out.println("Student()!!!");
}
public Student(String name){
this.myName = name;
System.out.println("Student(String)!!!");
}
public Student(String name,int age){
this.myName = name;
this.age = 18;
System.out.println("Student(String)!!!");
}
}
public class TestDemo2 {
public static void main(String[] args) {
Student student = new Student();
System.out.println("====================");
Student student2 = new Student("YaRu");
System.out.println(student2.getMyName());
System.out.println("====================");
Student student3 = new Student("YaRu",10);
System.out.println(student3);
}
}
运行结果:
Student()!!!
====================
Student(String)!!!
YaRu
====================
Student(String)!!!
Student{myName='YaRu', age=18}
结论: 调用完,构造方法后,对象才真正的存在了。
问题:this代表的是当前对象?(×)
public Student(String name){
this.myName = name;
System.out.println("Student(String)!!!");//构造对象的过程中
} //才是构造好了对象,还没有产生对象,this代表当前对象的引用
- 之前没有学习构造方法之前,也是new Student();->当你没有在类当中写任何构造方法时,编译器会自动为你提供一个不带有参数的构造方法,这个方法什么都没有做
- 当你在类中写了其他构造方法时,编译器就不会为你自动生成默认的构造方法。
快捷键,Alt+Inset,选择Constructor - 构造方法是否可以发生重载???可以的
方法名相同,参数列表不同,返回值不做要求,在一个类当中
如下图,方法名都是Student,参数列表不同,返回值不做要求,在一个类当中
this
上面的相关知识点里面多多少少都出现了this的用法,下面,来看this的一个新的用法。
代码示例:
class Student{
private String myName;
private int age;
public Student(){
this("YaRu");//调用带有一个参数的构造方法,
//且这个参数是String,如果要调用新的构造方法,需要写在第一行
System.out.println("student()");
}
public Student(String name){
System.out.println("student(String)");
this.myName = name;
}
}
public class TestDemo2 {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student);
}
}
打印结果:
student(String)
student()
Student{myName='YaRu', age=0}
this的三个作用:
- this.成员变量–>这里的成员变量一定是普通的成员变量,不能是静态的成员变量
- this();构造方法
- this.成员方法
public void func(){
System.out.println("func()");
}
public void func2(){
this.func();
System.out.println("func2()");
}