1. 定义类
java代码映射成现实事物的过程就是定义类的过程。
public class 类名{属性定义修饰符 数据类型 变量名 = 值方法定义修饰符 返回值类型 方法名(参数列表){}}
2. 使用类
实现引用类型的步骤
- 1: 导入包 , 类都是在同一个文件夹,不需要导入包
- 2: 创建引用类型的变量
3: 变量.方法
// 1:导包import com.henry.Phone;public class TestPhone{public static void main(String[] args){// 2: 创建引用类型的变量Phone p = new Phone();System.out.println(p); //输出内存的地址//3: 变量.类型中的功能//变量 p.的方式,调用类中的属性//属性就是变量 , 赋值和获取值p.color = "土豪金";p.brand = "爱立信";p.size = 5.0;//获取属性值System.out.println(p.color+" "+p.brand+" "+p.size);}}
3. Attribute 成员变量
成员变量和局部变量的区别
区别一:定义的位置不同
- 定义在类中的变量是成员变量
- 定义在方法中或者{}语句里面的变量是局部变量
- 区别二:在内存中的位置不同
- 成员变量存储在heap中
- 局部变量存储在stack中
- 区别三:声明周期不同
- 成员变量随着对象的出现而出现在堆中,随着对象的消失而从堆中消失
- 局部变量随着方法的运行而出现在栈中,随着方法的弹栈而消失
区别四:初始化不同
构造方法没有返回值类型。也不需要写返回值。因为它是为创建对象的,对象创建完,方法就执行结束。
- 构造方法名称必须和类型保持一致。
每一class类都必须有一个构造方法,构造方法不写也有。编译的时候,javac,系统会自动检查类中是否有构造方法,如果没有编译器就会自动添加一个构造方法
class Person {// Person的成员属性age和nameprivate int age;private String name;// Person的构造方法,拥有参数列表Person(int a, String nm) {// 接受到创建对象时传递进来的值,将值赋给成员属性age = a;name = nm;}}
B. 构造方法的内存加载过程
有一个Person类,创建Person 对象new Person()
1、首先会将main方法压入栈中,执行main方法中的 new Person(23,”张三”);
2、在堆内存中分配一片区域,用来存放创建的Person对象,这片内存区域会有属于自己的内存地址(0x88)。然后给成员变量进行默认初始化(name=null,age=0)。
3、执行构造方法中的代码(age = a ; name = nm;),将变量a对应的23赋值给age,将变量nm对应的”张三赋值给name,这段代码执行结束后,成员变量age和name的值已经改变。执行结束之后构造方法弹栈,Person对象创建完成。将Person对象的内存地址0x88赋值给p2。C. 构造方法的重载
1、一个类中可以有多个构造方法,多个构造方法是以重载的形式存在的
2、构造方法是可以被private修饰的,作用:其他程序无法创建该类的对象。//让一个类不能被实例化class Person {private int age;private String name;// 私有无参数的构造方法,即外界不能通过new Person();语句创建本类对象private Person() {}}
D. 构造方法和一般方法区别
- 格式不同: 构造方法没有返回值,一般方法必须有返回值。
- 作用不同:构造方法在对象创建时就执行了,而且只执行一次。一般方法是在对象创建后,需要使用时才被对象调用,并可以被多次调用。
- 调用方式不同:构造方法new对象时调用, 或者this() super() 语句调用。普通方法需要对象调用或者直接用类调用静态方法。
E. this在构造方法之间的调用
- 构造方法之间的调用,可以通过this关键字来完成。
构造方法调用格式:this(参数列表);
class Person {private int age;private String name;private Person(String name) {this.name = name;}public Person(String name, int age) {this(name);this.age = age;}}
F. super在构造方法之间的调用
子类的构造方法必须调用父类的构造方法且必须在第一句就调用super()。 即子类在初始化时,必须先到父类中去执行父类的初始化动作。这样,才可以使用父类中的内容。
构造方法第一行,写this()还是super()?this() 是调用本类的构造方法,super()是调用父类的构造方法, 且两条语句不能同时存在。无论如何,子类的所有构造方法,直接或间接必须调用到父类构造方法;class Student extends Person {String id;public Student(String name, int age, String id){super(name, age);this.id = id;}}
5. final
final是个修饰符,它可以用来修饰类,类的成员,以及局部变量。
修饰类:final修饰类不可以被继承,但是可以继承其他类。
- 修饰方法: final修饰的方法不可以被覆盖,但子类可以调用。
- 修饰局部变量:
- 修饰基本类型变量:final修饰的变量称为常量,这些变量只能赋值一次。
- 修饰应用类型变量:引用类型的变量值为对象地址值,地址值不能更改,但是地址内的对象属性值可以修改。
修饰成员变量:需要在创建对象前赋值,否则报错。当没有显式赋值时,多个构造方法的均需要为其赋值。
class Demo {//直接赋值final int m = 100;//final修饰的成员变量,需要在创建对象前赋值,否则报错。final int n;public Demo(){//可以在创建对象时所调用的构造方法中,为变量n赋值n = 2016;}}
6. static
对于一个Student类,每个student都有一个共同的属性— schoolName。如果让每个实例都单独分配一块空间去存储相同的内容,那么会造成极大的内存浪费。因此,如果一个类所有实例都可以共享一个属性值,那么上面的问题也就迎刃而解了。 此时,static的概念就被引入。
A. 特点
被static修饰的成员变量属于类,不属于这个类的某个对象。
- 被static修饰的成员可以并且建议通过类名直接访问。
- 被static修饰的method只能调用 static method 和 static attribute
- 由于上面原因,static method中不能使用this关键字。
B. static的内存
- 静态变量,静态方法,静态块等都是类级别的属性,而不是单纯的对象属性。他们在类第一次被使用时被加载(记住,是一次使用,不一定是实例化)
- 当一个对象初始化时总是先加载自己的静态成员.
C. static的使用场景:
- 一般我们把共性数据定义为static属性
- 如果静态方法中引用到了静态的其他成员,那么这个方法需要声明为static方法
如果一个方法不会操作类中的任何成员,那么这个方法应该被声明为static方法
D. static 在多态中调用
在多态调用中,我们必须弄清楚编译看谁,运行看谁
对于方法,编译都看 = 左边的父类, 父类有成员变量或方法则编译成功,没有则失败。
运行: 静态方法看父类中的静态方法。非静态方法看子类的重写方法-
7. Anonymous Object
匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。
public class Person{public void eat(){System.out.println();}public static Person getPerson(){return new Person(); //匿名对象作为方法返回值}public static void main(String[] args){new Person().eat();}}
