二、面向对象
1.类的定义、对象的创建
public class Dog{
public String name;
public int age;
public double weight;
public void run() {
System.out.println(name + "is running.");
}
public void eat(String food) {
System.out.println(name + "is eating an " + food +
".\nIt's age is " + age + ".\nIt's weight is " + weight + ".");
}
public static void main(String[] args) {
Dog adog = new Dog();
adog.name = "风";
adog.age = 1;
adog.weight = 15.5;
adog.run();
adog.eat("apple");
}
}
成员变量(Member Variable)= 字段(Field)
2.对象的内存
- Java中所有对象都是new出来的,所有对象的内存都是在堆空间,所有保存对象的变量都是引用类型
- Java运行时环境有垃圾回收器(garbage collector,简称GC),会自动回收不再使用的内存
3.Java程序的内存划分:
Java虚拟机在执行Java程序时会将内存划分为若干个不同的数据区域,主要有:
- PC寄存器(Program Counter Register):存储Java虚拟机正在执行的字节码指令的地址;
- Java虚拟记栈(Java Virtual Machine Stack):存储栈帧;
- 堆(Heap):存储GC所管理的各种对象;
- 方法区(Method Area):存储每一个类的结构信息(比如字段和方法信息、构造方法和普通方法);
- 本地方法栈(Native Method Stack):用来支持native方法的调用(比如C语言编写的方法)
4.构造方法
构造方法,也叫构造器,能够方便地创建一个对象
- 方法名必须和类名一样;没有返回值类型;可以重载
public class Dog{
public String name;
public int age;
public Dog(){
}
public Dog(String name, int age){
this.name = name;
this.age = age;
}
}
- this是一个指向当前对象的引用,常见用途有:访问当前类中定义的成员变量;调用当前类中定义的方法(包括构造方法)
public class dog{
public double weight;
public int age;
public dog(){
this(0,0);//重复调用下面的构造方法
//构造方法调用了其他构造方法,此调用语句一定要放在此构造方法的第一条
}
public dog(double weight, int age){
this.weight = weight;
this.age = age;
}
}
- this的本质是一个隐藏的、位置最靠前的方法参数
public class Dog{
public String name;
public void eat(){ //public void eat(Dog this)
System.out.println(name + "eat."); // ……(this.name + "eat.");
}
public static void main(String[] args){
Dog aDog = new Dog;
aDog.name = "哈士奇";
aDog.eat(); //等价于 方法区 > run(aDog);
}
}
- 默认构造方法:如果一个类没有自定义构造方法,编译器会自动为它提供无参数的默认构造方法;一旦定义了构造方法,默认构造方法就不再存在
- 建议写一个无参的构造方法
5.包(package)
-
Java中的包就是其他编程语言的命名空间,包的本质是文件夹,常见作用有: 将不同的类进行组织管理、访问控制;解决命名冲突
-
命名建议:保证包名唯一性,一般包名都是以公司域名的倒写开头,比如com.baidu*(如果公司域名有非法字符,建议增加_来使包名合法化);全小写(避免和某些类名或者接口名冲突)
-
类的第一句代码必须使用package声明自己属于哪个包
-
如何使用一个类:(必须知道这个类的具体位置,即在哪个包)
a.使用类的全名
b.使用import导入指定的类名
c.使用import导入整个包的所有类(包名.*) -
为了方便,Java编译器会为每个源文件自动导入2个包:java.lang.*、源文件所在包.**
-
import.aa.bb.*;仅仅是导入了直接放在aa.bb包中的类
-
Eclipse导包快捷键 Ctrl + Shift + O,也可以使用Ctrl + 1修复错误来导包
6.继承(Inheritance)
- 关键字:extends
- 任何类最终都继承自java.lang.Object
- 子类可以定义跟父类同名的成员变量(不推荐这么做)
//Animal类
public class Animal{
public int age = 1;
}
//Dog类
public class Dog{
public int age = 2;
public void show() {
System.out.println(age); // 2
System.out.println(this.age); // 2
System.out.println(super.age); // 1
}
public static void main(String[] args) {
Dog aDog = new Dog();
aDog.show();
}
}
7.方法的重写(Override)
-
重写:子类的方法签名和父类一样。也叫做覆盖、覆写
-
子类override的方法权限必须 >= 父类的方法权限
子类override的方法返回值必须 <= 父类的方法返回值类型(子类 <= 父类) -
super的常见用途是:访问父类中定义的成员变量;调用父类中定义的方法(包括构造方法)
-
子类的构造方法必须先调用父类的构造方法,再执行后面的代码;如果没有显式调用,编译器会自动调用父类无参的构造方法(父类没有无参的,则报错)
//Animal类
public class Animal{
public int age;
public Animal(int age){
this.age = age;
}
}
//Dog类
public class Dog extends Animal{
public String name;
public Dog(String name){
super(1);
this.name = name;
}
public static void main(String[] args){
}
}
8.注解(Annotation)
2个常见的注解:
@Override:告诉编译器这是一个重写后的方法
@SuppressWarnings(“警告类别”):让编译器不生成警告信息
9.访问控制(Access Control)
修饰符 | Value |
---|---|
public | 任何地方均可见 |
protected | 自己包中、自己子类可见 |
private | 自己包中可见 |
无修饰符(package-private) | 仅在自己类中可见 |
- 上述4个访问权限都可以修饰类的成员,比如成员变量、方法、嵌套类(Nested Class)等
- 只有public、无修饰符可以修饰顶级类(Top-level Class)
- 上述4个访问权限不可以修饰局部类(Local Class)、局部变量
- 一个Java源文件中可以定义多个顶级类、public顶级类的名字必须和文件名一样
10.封装
- 成员变量private化,提供public的get、set方法
11.toString方法
- 当打印一个对象时,会自动调用对象的toString方法,并将返回的字符串打印出来
- toString方法来源于基类java.lang.Object,默认实现:
public String toString(){
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
- Eclipse中有一个可以自动生成get、set、constructor、toString等常用代码的快捷键:Shift + Alt + S