封装的定义
- 封装(Encapsulation):
是指隐藏对象的属性和实现细节。仅对外提供公共访问方式 - 好处:
将变化隔离
便于使用
提高重用性
提高安全性 - 代码中体现:
函数本身就死最小的封装体,其次到类、包、框架
private修饰符的出现,修饰类中的成员(成员变量、成员函数)将其变成私有,私有类只有在本类中有效。
构造函数
- 何为构造函数:
函数名和类名一致
不用定义返回值类型(与void不同。)
不可以写return语句
- 构造函数作用:
给对象进行初始化
- 什么时候定义构造函数:
当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中 - 与一般函数的区别:
-
在运行上有不同,构造函数在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,给对象添加对象具备的功能
-
调用次数上,一个对象建立,构造函数只运行一次。而一般方法可以被该对象调用多次。
注意:当一个类中没有定义构造函数时,系统会默认给该类加入一个空参数的构造函数如:【Person(){}】
当在一个类中,自定义了构造函数后,默认的构造函数就没有了。多个构造函数是以重载的形式存在的
构造代码块
定义对象共性初始化内容,不同对象的共性定义在构造代码块里
- 作用:
给对象进行初始化(对象一建立就运行,而且优先于构造函数执行)
- 和构造函数的区别:
构造代码块是给所有对象进行统一初始化
而构造函数是给对应的对象初始化
- 语法
{
语句1
}
举例
this关键字
-
作用:
- 区别成员变量和局部同名的时候用
- 构造函数间的调用(一般函数不能调用构造函数的)
-
解析
当定义类中的功能时,该函数内部要用到这个函数的对象时,这时用this来表示这个对象。但凡本类功能用到本类对象,都用this表示。比如:
class Person{
private String name;
private int age;
Person(int age){
this.age=age;
System.out.println("age="+age);
}
/*
*需求:给人定义一个用于比较年龄是否相同的功能,也就是是否是同龄人
*/
public boolean Compare(Person p){
return this.age==p.age;
}
}
public class PersonDemo2 {
public static void main(String[] args) {
Person p1=new Person(20);
Person p2=new Person(25);
boolean b = p1.Compare(p2);
System.out.println(b);
}
}
Person方法里的this,当p1 和p2都分别创建对象时,this就分别代表p1 和p2。
Compare方法里的this,当p1对象调用它时,this代表的就是p1
构造函数间调用只能用this语句
初始化动作先执行,再执行自己的初始化,this语句要放在构造函数的第一行,因为构造函数只执行一次
为什么构造函数间需要相互调用,对外提供一个构造函数,但内部初始化方式可以通过调用不同私有化的构造方法进行初始化。
23行,表示对象调用了16行的构造函数对name再一次进行初始化,这也就是构造函数间调用。
Static关键字
- 用法:
是一个修饰符,用于修饰成员(成员变量和成员函数)
静态所修饰的内容,被对象所共享。当成员被静态修饰后,就多了一种调用方式,除了可以被对象调用外,还可以直接被类名调用 - 写法:
类名.静态成员
当多个对象当中,存在共同的数据。创建对象越多,共同的数据就越多,为了不浪费内存,所以将共同的数据抽出,让对象去访问,比如相同国籍的学生。
static String country=“CN”
特有内容随着对象存储在堆内存中,像每个人的名字
- 方法区(共享区 数据区)
类中的方法、类中的共享数据存放这边。 - 静态的特点:
- 随着类的加载而加载,也就是说静态随着类的消失而消失。说明他的生命周期最长。
- 优先于对象存在(静态是先存在,对象是后存在的)
- 被所有对象所共享
- 可以直接被类名所调用
- 实例变量和类变量的区别:
String name;//成员变量,实例变量
static String country ="CN";//静态的成员变量,类变量
1. 存放位置:
类变量随着类的加载而加载,存放于方法中,
实例变量随着对象的建立而存在堆内存中。
2. 生命周期:
类变量生命周期最长,随着类的消失而消失
实例变量生命周期随着对象消失而消失
- 静态的使用注意事项:
- 静态方法只能访问静态成员(方法和变量)
- 非静态方法既可以访问非静态也可以访问静态成员
- 静态方法中不可以定义this super关键字,因为静态优先于对象存在
- 主函数是静态的。(主函数是一个特殊的函数,作为程序入口,可以被jvm调用
- 静态的好处:
- 对对象共享数据进行单独空间存储,节省内存空间,没有必要每个对象都存一遍
- 可以直接被类名调用。
- 弊端:
- 生命周期过长,
2.访问出现局限性(静态虽好,但是只能访问静态)
- 什么时候使用静态?(因为静态修饰内容有成员变量和函数)
- 什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰(值一样)
对象中持有数据要定义成非静态存在于堆内存中 - 什么时候定义静态函数呢?
当功能内容没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。
静态代码块
特点:随着类的加载而执行,只执行一次
用处:用于给类进行初始化的,优先于主函数执行
语法:
static {
语句;
}
执行顺序
new StaticCode(4);时,静态优先于对象。所以会优先打印a
构造代码快优先于构造函数。
所以打印出:a c9 d
class StaticCode{
int num =9;
StaticCode(){
System.out.println("b");//因为没有创建没带参数的对象,所以不会执行
}
static {
System.out.println("a");//静态代码块给类初始化 num不能放这,因为静态不能写this
}
{
System.out.println("c"+this.num);//构造代码块给对象初始化
}
StaticCode(int x) {
System.out.println("d");//构造函数给对应对象初始化,因为创建了带参数的对象
}
}
public class StaticCodeDemo {
public static void main(String[] args) {
new StaticCode(4);
System.out.println("over!");
}
}
对象初始化过程
对象创建过程:
第一步:new的时候将Person.class文件加载进内存。
第二步;静态代码块执行(优先于对象) 因为执行的时候name为空,age为0都是堆内存的初始值。
第三步:堆内存开辟空间,则有属性(name age)
第四步:构造代码块的优先级比构造函数高,
默认初始化-》显示初始化-》构造代码块初始化-》构造函数初始化
显示初始化