顾名思义,就是在一个数组内体现多态
public class PolyArrDemo {
public static void main(String[] args) {
// 定义多态数组
Fruit[] fruits = new Fruit[3];
fruits[0] = new Fruit();
fruits[1] = new Orange();
fruits[2] = new Pear();
for (Fruit fruit : fruits) {
// 根据动态绑定原理,输出不同的值
fruit.say();
}
}
}
class Fruit {
public void say() {
System.out.println("this is fruit");
}
}
class Pear extends Fruit {
@Override
public void say() {
System.out.println("pear");
}
}
class Orange extends Fruit {
@Override
public void say() {
System.out.println("orange");
}
}
如果你想要特定的调用每个子类中的新定义的方法
可以先使用 instanceOf
判断当前对象是不是子类的一个实例,如果是,再执行调用
所以上文的 for 循环体内可以加个判断,写成下面的样子(我为 Orange 添加了新方法 eatOrange,这里不给出,大家自己实现即可)
for (Fruit fruit : fruits) {
if (fruit instanceof Orange) ((Orange) fruit).eatOrange();
fruit.say();
}
==
有两种作用
下面的赋值方法为引用赋值,故之间地址比较均为 true
A a = new A();
A b = a;
System.out.println(a==b); // true
hashCode 用于返回一个对象的哈希值,用于提升哈希表效率
两个引用指向同一对象,哈希值必定一致;
哈希值一致不一定表示引用指向同一对象;
哈希值不完全等于地址值
对象被垃圾回收时,自动调用的方法;
可以重写该方法,让对象再被释放资源前做一些什么;
采用引用计数法,当 JVM 发现某个对象的引用次数为 0 时,就会执行垃圾回收程序来释放该对象资源
GC 机制由系统决定,当然也可以使用 System.gc()
主动触发回收
类变量实际上就是普通变量加上一个 static
也称为静态变量
该变量会被该类的所有实例所共享;
class A{
public static int count = 0;
}
直接使用 类名.类变量名
来执行访问
没有加上 static 的就是所谓的实例变量
类被加载时,类变量就初始化完毕了,就是说你无需实例化对象就可以直接从类调用该类变量
类变量的生命周期是:类初始化开始到其销毁为止
类方法也就是静态方法
普通方法加上一个 static 即可,具体调用方法和作用可以直接参考类变量
类方法可以通过类名调用,也可以通过对象名调用;
类方法随类的初始化而加载,结构信息存储于方法区;
类方法无 this 参数,而普通方法有 this 参数;
静态方法只能访问静态的成员(即静态属性和静态方法);普通方法则无限制
由于 main 方法自己就是一个静态方法,故也只能调用同类内的静态成员
对于普通成员,则需要实例化自身再执行调用
package chapter2;
public class MainDemo {
public static void main(String[] args) {
// 静态方法可以直接调用
MainDemo.func1();
// 非静态方法必须实例化自身才可以调用
MainDemo mainDemo = new MainDemo();
mainDemo.func2();
}
public static void func1(){
System.out.println("static function");
}
public void func2(){
System.out.println("normal function");
}
}
众所周知,main 方法接收一个 args 字符串数组,用于命令行添加可变长参数
所以当我们使用命令行执行 java 程序是,可以传入任意长度的参数:
java [类名称] asd asd asd
代码块有两种:static 代码块和普通代码块
static 代码块可看做对类的初始化,它随着类的加载而执行,且仅执行一次;
普通代码块是当每个对象被创建就执行一次;
类被加载的时刻:
普通代码块只有在对象实例化才会被调用,故我们直接使用类内静态成员而不实例化对象,是不会触发普通代码块的!
创建一个类时,对应的调用顺序:
创建一个子类是,对应的调用顺序
class Single1 {
private Single1() {
}
private static final Single1 instance = new Single1();
public static Single1 getInstance() {
return instance;
}
}
class Single2 {
private Single2() {
}
private static Single2 instance;
public static Single2 getInstance() {
if (instance == null) {
instance = new Single2();
}
return instance;
}
}