第四章 面向对象基础
1.对象和类
面向对象的三大特征:封装、继承、多态。
类:class 对象:Object,instance 类的实例化
2.类的定义
一个源文件只能有一个public class,可以有多个class。
一个类一般有三种常见成员:属性field、方法method、构造器constructor。都可以有0个或者多个。
3.构造方法及其重载
public class User {
int id; // id
String name; // 账户名
String pwd; // 密码
public User() {
}
//构造器也叫构造方法
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
//构造方法的重载
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public static void main(String[] args) {
User u1 = new User();
User u2 = new User(101, "高小七");
User u3 = new User(100, "高淇", "123456");
}
}
4.垃圾回收机制
JAVA对内存的管理很大程度上指对象的管理,包括对象空间的分配(new 实例化)和释放(将对象赋值为null)。
垃圾回收过程:1.发现无用对象(没有任何变量引用的对象) 2.释放无用对象的空间
垃圾回收算法:
1.引用计数法:堆中的对象被引用一次计数加1;对象被赋值为null,计数减1。当计数为0时则释放。缺点:无法识别循环引用的无用对象。
例如:
public class Student {
String name;
Student friend;
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.friend = s2;
s2.friend = s1;
s1 = null;
s2 = null;
}
}
2.引用可达法:从一个节点开始寻找引用节点,让后继续寻找,当所有节点的引用节点寻找完之后,剩余节点被认为是无用节点。
5.分代垃圾回收
1、新创建的对象,绝大多数都会存储在Eden中,
2、当Eden满了(达到一定比例)不能创建新对象,则触发垃圾回收(Minor GC),将无用对象清理掉,然后剩余对象复制到某个Survivor中,如S1,同时清空Eden区
3、当Eden区再次满了,会将S1中的不能清空的对象存到另外一个Survivor中,如S2,同时将Eden区中的不能清空的对象,也复制到S1中,保证Eden和S1,均被清空。
4、重复多次(默认15次)Survivor中没有被清理的对象,则会复制到老年代Old(Tenured)区中,
5、当Old区满了,则会触发一个一次完整地垃圾回收(FullGC),之前新生代的垃圾回收称为(minorGC)。
6.this关键字
this的本质就是“创建好的对象的地址”! 在构造方法中使用this指代当前对象。
this的最常用用法:
1.使用this来指明当前对象。普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。
public class User {
int id; //id
String name; //账户名
String pwd; //密码
public User(int id, String name) {
System.out.println("正在初始化已经创建好的对象:"+this);
this.id = id; //不写this,无法区分局部变量id和成员变量id
this.name = name;
}
public static void main(String[] args) {
User u3 = new User(101,"高小七");
System.out.println("打印高小七对象:"+u3);
}
}
2.使用this关键字调用重载的构造方法。必须位于第一行。
public class TestThis {
int a, b, c;
TestThis(int a, int b) {
// 这样就区分了成员变量和局部变量. 这种情况占了this使用情况大多数!
this.a = a;
this.b = b;
}
TestThis(int a, int b, int c) {
this(a, b); // 调用带参的构造方法,并且必须位于第一行!
this.c = c;
}
void sing() {
System.out.println("sing");
}
void eat() {
this.sing(); // 调用本类中的sing();
}
public static void main(String[] args) {
TestThis hi = new TestThis(1,2, 3);
hi.eat();
}
}
3.this不能用于static方法。
7.static关键字
1.静态成员变量(类变量)生命周期和类相同。
2.在static方法中不可直接访问非static的成员。
3.对于该类的所有对象,static成员变量只有一份,被所有对象共享。
4.可以直接使用类名调用。
5.静态初始化块,用于类的初始化操作!构造方法用于对象的初始化!
在静态初始化块中不能直接访问非static成员。(因为static最先初始化)
public class User {
int id; // id
String name; // 账户名
static String company = "university";
public User(int id, String name) {
this.id = id;
this.name = name;
}
public void login() {
printCompany();
System.out.println(company);
System.out.println("登录:" + name);
}
//5.静态初始化块,用于类的初始化操作!构造方法用于对象的初始化!
//在静态初始化块中不能直接访问非static成员。(因为static最先初始化)
static {
System.out.println("*******");
company = "jywang";
}
//2.在static方法中不可直接访问非static的成员。
public static void printCompany() {
//login();//调用非静态成员,编译就会报错
System.out.println(company);
}
//3.对于该类的所有对象,static成员变量只有一份,被所有对象共享。
//4.可以直接使用类名调用
public static void main(String[] args) {
User u = new User(101, "s");
User.printCompany();//4.可以直接使用类名调用
User.company = "school";
User.printCompany();
}
}
8.参数传递机制
1.值传递传递的是副本 2.引用类型传递的是地址
public class User4 {
int id; //id
String name; //账户名
public User4(int id, String name) {
this.id = id;
this.name = name;
}
public void testParameterTransfer01(User4 u){
System.out.println(u);
u.name="22222222";
}
public void testParameterTransfer02(User4 u){
//新创建了一个对象,有了新的地址
u = new User4(300,"3333333");
System.out.println(u);
}
public static void main(String[] args) {
User4 u1 = new User4(100, "111111111");
System.out.println(u1);
System.out.println(u1.name);
u1.testParameterTransfer01(u1);
System.out.println(u1.name);
u1.testParameterTransfer02(u1);
System.out.println(u1.name);
}
}