07--面向对象--封装+this关键字+构造器
封装
1.1概述:
封装是指隐藏对象的属性和实现细节,仅仅对外提供公共的访问方式。
1.2好处:
1、 提高安全性
2、 提高重用性
1.3 特点:
被封装后的资源,只能在本类中可见。如果别的类想用,需要提供公共的访问方式。
通过private关键字,实现封装。
可以封装成员变量或者成员方法。
1.4 private关键字
是一个权限修饰符,用于修饰成员变量和成员函数,被私有化的成员只能在本类中访问。
想要修改只能,对外提供公共的,get和set方法。
练习:封装学生类
package cn.tedu.privatedemo; //这个类用来测试 封装 //自动生成set() get() : 右键 - source - setters and getters - select all - ok public class Test1_Private { public static void main(String[] args) { //2、创建对象测试 Student s = new Student() ; // s.coding(); // 3.1、因为coding()被封装了,除了自己类中,别的类里都不能用。 s.game(); // s.name = "jack";//5.1 设置值失败,因为name被private了 // System.out.println(s.name);//5.1 获取值失败,因为name被private了 //7、调用公共的setName()设置值 s.setName("jack"); //8.1、调用公共的getName()获取值 String name = s.getName() ; System.out.println(name); // System.out.println(s.age); // System.out.println(s.score); s.setAge(20); s.setScore(99.9); System.out.println( s.getAge() ); System.out.println( s.getScore() ); } }
学生类:Student
//创建学生类 class Student{//5、使用private修饰成员变量,虽然可以提高安全性。但是,外界还想改,还想获取怎么办? private String name ; //6、如果外界想访问私有的成员变量,来访问公共的全局访问点 //7。1、外界可以访问公共的setXxx() 设置值。 public void setName(String n) { name = n ;//帮name属性设置值 } //8、可以访问公共的getXxx()获取值。 public String getName(){ return name ; //把name属性的值返回给外界调用位置 } //封装以下属性 + 提供set/get + 并测试 private int age ; private double score ; //set()用来设置值 public void setAge(int a) { age = a ; } public void setScore(double d) { score = d ; } //get()用来获取值 public int getAge(){return age ; } public double getScore(){return score ;} //3、通过private关键字实现封装,就只能在本类中使用。如果还想使用封装的资源,只能提供间接的访问方法 private void coding() { System.out.println("coding..."); } public void game() { coding() ;//4、间接访问private资源 System.out.println("game..."); } }
匿名对象
概念:没有名字的对象,是对象的简化表示形式。
使用场景: 当被调用的对象只调用一次时(多次会创建多个对象浪费内存)
优点:节省内存
缺点:使用时这个对象只执行一个任务
示例:
new Demo().show();//创建了一个对象调方法 new Demo().game();//又创建了一个对象调方法
创建对象的流程
1 Student s = new Student() ;//短短这行代码发生了很多事情 2 把Student .class文件加载进内存 3 在栈内存中,开辟空间,存放变量s 4 在堆内存中,开辟空间,存放Student 对象 5 对成员变量进行默认的初始化 6 对成员变量进行显示初始化 7 执行构造方法(如果有构造代码块,就先执行构造代码块再执行构造方法) 8 堆内存完成 9 把堆内存的地址值赋值给变量s,s就是一个引用变量,引用了Student 对象的地址值
构造方法
--1、概念:
是一个特殊的方法,特殊在这个方法名和类名相同。
专门用来完成对象的创建或者初始化。
可以存在方法重载现象。
--2、语法:
修饰符 类名([参数列表]){ 方法体 }
练习:构造方法创建对象
package cn.tedu.constructor; //这个类用来测试 构造方法 专门用来创建对象 //总结1:在我们创建对象时,会自动匹配构造方法。构造方法可以重载。 public class Test2_Cons { public static void main(String[] args) { //1、无参方式创建对象 --- 会自动调用 无参构造方法! Person p = new Person() ;//会自动调用 无参构造方法 //4、创建对象 -- 触发 含参构造 Person p2 = new Person("钟爷爷");//会自动调用 String构造方法 Person p3 = new Person(20);//会自动调用 int构造方法 Person p4 = new Person("钟南山",85);//会自动调用 String,int构造方法 } } //创建Person类 //修饰符 类名([参数列表]){ 方法体 } class Person{ //2、无参 构造方法 是默认存在的! 前提是:如果类中,只提供了含参构造,此时无参构造就真的没有了!!! public Person() { } //3、提供重载形式的构造方法:方法名相同+参数列表不同 public Person(String name) { System.out.println("含参构造方法"+name); } //重载形式的构造方法 public Person(int age) { System.out.println("含参构造方法"+age); } public Person(String name,int age) { System.out.println("含参构造方法"+name+age); } }
注意:
1、无参方式创建对象 --- 会自动调用 无参构造方法
2、无参 构造方法 是默认存在的! 前提是:如果类中,只提供了含参构造,此时无参构造就真的没有了!!!
3、提供重载形式的构造方法:方法名相同+参数列表不同
4、一般为了方便创建对象,都将无参构造方法显式的写出来.
练习:构造方法赋值
在创建对象时,可以用含参的方式创建对象。同时把参数会传递给构造方法。构造方法拿到值就给成员变量直接赋值。
package cn.tedu.constructor; //这个类用来测试 构造方法 给成员变量赋值 public class Test3_Cons { public static void main(String[] args) { Animal a = new Animal() ; //会自动触发 无参构造 Animal a2 = new Animal(3) ; //会自动触发 含参构造 } } class Animal{ private int age ; //默认就会存在 无参 构造 !! public Animal( ) { } public Animal(int a) { age = a ;//创建对象时,传递过来的参数,交给了a保存。a拿到值,给成员变量age赋值。 System.out.println(age); } }
构造代码块和局部代码块
代码块
--1、代码块: 有一个定功能。 { 代码块 }
--2、代码块的位置不同,作用和功能完全不同。
构造代码块
如果是在成员位置(类里方法外)的代码块 叫 构造代码块
构造代码块:位置是在成员位置+优先执行构造代码块再执行构造方法+用来提取构造方法的共性
局部代码块
如果是在局部位置(方法里)的代码块 叫 局部代码块
局部代码块:位置是在局部位置+作用用来控制变量的作用范围
测试
package cn.tedu.constructor; //这个类用来测试 代码块 //1、构造代码块特点:在触发构造方法前先去执行构造代码块 + 用来抽取构造方法的共性 + 位置是在成员位置 //2、局部代码块特点:触发了方法 + 用来控制变量的作用范围 + 位置是在方法里 //3、执行顺序:创建对象时,先触发构造代码块再触发构造方法。调用方法后,触发局部代码块。构造代码块>构造方法>局部代码块 public class Test4_Block { public static void main(String[] args) { Teacher t = new Teacher(); Teacher t2 = new Teacher(20); Teacher t3 = new Teacher("钟南山"); //2、 每次 创建对象时 ,都会自动调用构造方法。但是,每次调用构造方法前,都先去调用构造代码块。 //3、一定是先加载构造 代码块 再加载 构造方法。 t.show();//7、触发show(),来执行局部代码块 } } class Teacher { String country ;//5、由于所有构造方法都需要使用相同的变量country,所以需要把country声明成一个成员变量,在整个类中生效 //1、构造代码块:位置是在类里方法外 { country ="中国人" ; //4、构造代码块 专门 用来 抽取所有 构造方法的共性!! System.out.println("构造代码块"); } public Teacher() { System.out.println("无参构造"+country); } public Teacher(int a) { System.out.println("含参构造" + a + country); } public Teacher(String n) { System.out.println("含参构造" + n + country); } //6、局部代码块:位置是在方法里,想要执行,必须先触发方法。 + 用来 控制变量的作用范围(只在局部代码块内有效) public void show() { { int sum = 10 ; System.out.println("局部代码块"); System.out.println(sum); } } }
this关键字
概念:
this代表本类对象的一个引用对象。
构造函数中,this()必须放在第一行。
this的本质就是“创建好的对象的地址”
要点:(转载)
1、this不能用于static方法中
2、由于在构造器调用之前,对象已经创建,因此在构造器中可以使用this(this代表当前对象)
3、在构造器的重载中使用this,this必须在构造器的第一句
1、this不能用于static方法中
2、由于在构造器调用之前,对象已经创建,因此在构造器中可以使用this(this代表当前对象)
3、在构造器的重载中使用this,this必须在构造器的第一句
练习:当变量名相同时
package cn.tedu.thisdemo; //这个类用来测试 this关键字 public class Test5_This { public static void main(String[] args) { new Demo().show(); } } //创建Demo class Demo{int count = 30 ; public void show() { int count = 10 ; System.out.println(count);//10,变量的就近原则//1、this用来表示本类对象的引用 //2、当局部变量名 和 成员变量名同名 时,可以通过this来调用成员变量。否则,你会一直使用局部变量。 System.out.println( this.count ); //30 } }
练习:构造方法间互相调用
无参构造调用有参构造和有参构造调用无参构造不能够同时出现
this关键字,使用在构造方法中时,必须是第一条语句!!!
package cn.tedu.thisdemo; //这个类用来测试 this关键字 public class Test5_This { public static void main(String[] args) { //4、无参创建对象 -- 自动触发 无参构造 new Demo() ; //6、含参创建对象 -- 自动触发 含参构造 new Demo(88); } } //创建Demo class Demo{ //构造方法 public Demo() { //3、在无参构造中 使用 含参构造 的功能 // this(100); System.out.println("无参构造"); } public Demo(int age) { //5、在含参构造中 使用 无参构造 的功能 this();//7、this关键字,使用在构造方法中时,必须是第一条语句!!! System.out.println("含参构造"+age); } }