Java类和对象(一)
一、类和对象的基础知识
类,相当于模板、模子。对象。相当于实体。一个类可以产生多个对象。
class Person {
public int age;//成员变量(属性)、字段
public String name;
public static int num;//静态成员变量
//成员方法
public void eat() {
System.out.println("eat!");
}
public void sleep() {
System.out.println("sleep!");
}
}
public class Test {
public static void main(String[] args) {
Person p = new Person();//实例化对象
Person p1 = new Person();
p.age = 11;
p.name = "pp";
p.eat();//成员方法调用,通过对象调用
}
具体的实现思路如下图:
根据这个图,就可以发现静态成员变量不属于对象,它存储在方法区中。普通成员变量存储在堆中,局部变量储存在栈中,且局部变量存储的内容实际是地址。
注意:
成员变量和局部变量在初始化方面是有所不同的。成员变量有默认值,可以不初始化,但是局部变量必须初始化。
对于各种数字类型,默认值都为0,boolean类型默认值为false类型。
二、static
static修饰过的变量,不属于类的对象。对于静态成员变量和静态方法,只能通过类调用,不能通过对象调用(虽然在IDEA中可以编译成功,但是警告状态,不推荐使用)。
class Person {
public static int num;//静态成员变量
public void sleep() {
System.out.println("sleep!");
}
public static void fight() {
System.out.println("fight!");
}//静态方法
}
public class Test {
public static void main(String[] args) {
Person p = new Person();
//yes
Person.num = 19;
Person.fight();
//error
p.num = 12;
p.fight();
}
}
除此之外,static修饰的变量和方法仍有注意的地方。
在静态方法中,不能直接使用非静态成员变量和调用非静态方法
原因:静态方法和静态变量不使用对象,直接利用类调用。而,非静态的变量和方法必须使用对象。所以,如果在静态方法中使用非静态的变量和方法,则是产生矛盾的。但是反过来的话,不影响使用。
在下面这个例子中,有着更好的展现。
class Person {
public int age;//普通成员变量
public String name;
public String sex;
public static int num;
public static int size;
//普通的成员方法
public void eat() {
int a = 10;//yes
num = 2;//yes
fight();//yes
System.out.println("eat()");
}
//静态成员方法
public static void fight() {
name = "aa";//error
size = 10;//yes
eat();//error
System.out.println("fight()!");
}
}
三、封装
面向对象的语言有些特征:继承、封装、多态、组合等。
实现封装:private修饰成员变量。private修饰的成员变量只能在当前类中使用。对私有的成员变量,进行赋值和获取操作能通过函数获得。
class Person {
private int age = 18;
private String name = "p";
public void show() {
this.name = "pp";//yes
System.out.println("name is "+name+" age is "+age);
}
}
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.show();
// p.age = 18;//error
// p.name = "pp";//error
}
}
根据上面的代码,发现private修饰的成员变量只能在当前类中使用,这时使用this关键字。但是不能在别的类中使用。
this关键字
this是当前对象的引用,不是当前对象。
在下面的代码中,直到最后一个 } 运行完,才构造好对象。所以,this.name 是在构造对象的过程中。所以,如果this 是当前对象,那么和这个例子是不符的。
补充:调用完构造方法后,对象才真正存在。
public Person (String name) {
this.name = name;
System.out.println("Person(String!)");
}