KeyWord
instanceof和类型转换
instanceof
System.out.println(object instanceof class);
object 任意对象表达式
class 任意已定义的对象类
输出的结果是true还是false,主要是看变量object所指向的对象实际类型是不是class类型的“子类型”
instanceof在Java的编译状态和运行状态是有区别的:
在编译状态中,class可以是object对象的父类,自身类,子类。在这三种情况下Java编译时不会报错。
在运行状态中,class可以是object对象的父类,自身类,不能是子类。在前两种情况下result的结果为true,最后一种为false。但是class为子类时编译不会报错。运行结果为false。
类型转换
-
父类引用可以指向子类对象,子类引用不能指向父类对象
-
把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转型
-
把指向子类对象的父类引用赋给子类引用叫downcasting向下转型,要强制转型
如father就是一个指向子类对象的父类引用,把father赋给子类引用son 即
Son son = (Son) father;
其中father前面的(Son)必须添加,进行强制转换
-
upcasting会丢失子类特有的方法,但是子类overriding(重写)父类的方法,子类方法有效
-
向上转型的作用,减少重复代码,父类为形式参数,调用时用子类作为实参,就是利用了向上转型。这样使代码变得简洁。体现了java的抽象编程思想
static修饰符
static变量
在类中,使用static修饰的成员变量,就是静态变量,否则就是非静态变量
静态变量和非静态变量的区别
静态变量属于类的,"可以"使用类名来访问,非静态变量是属于对象的,"必须"使用对象来访问。
静态变量对于类而言,在内存中只有一个,能被类的所有实例共享。实例变量对于类的每个实例都有一份,它们互不影响
在加载类的过程中为静态变量分配内存,实例变量在创建对象时分配内存,所以静态变量可以使用类名来直接访问,而不需要使用实例对象来访问
static方法
在类中,使用static修饰的成员方法,就是静态方法,否则为静态方法
静态方法和非静态方法的区别
静态方法属于类的,"可以"使用类名来调用,非静态方法是属于对象的,"必须"使用对象来调用
静态方法"不可以"直接访问类中的非静态变量和非静态方法,但是"可以"直接访问类中的静态变量和静态方法
注意 this和super在类中属于非静态的变量。(静态方法中不能使用)
非静态方法"可以"直接访问类中的非静态变量和非静态方法,也"可以"直接访问类中的静态变量和静态方法
父类的静态方法可以被子类继承,但是不能被子类重写
父类的非静态方法不能被子类重写为静态方法
代码块和静态代码块
【类中可以编写代码块和静态代码块】
public class person{
{
//代码块(匿名代码块)
}
static{
//静态代码块
}
}
【匿名代码块和静态代码块的执行】
因为没有名字,在程序中不能主动调用这些代码块。
匿名代码块是在创建对象的时候自动执行的,并且在构造器执行之前。
同时匿名代码快在每次创建对象的时候都会自动执行。
静态代码块是在类加载完成之后就自动执行,并且只执行一次。
注意:每个类在第一个被使用的时候就会被加载,并且一般只加载一次。
【匿名代码块和静态代码块的作用】
- 匿名代码块的作用是给对象的成员变量初始化赋值,但是因为构造器也能完成这项工作,所以匿名代码块的使用并不多。
- 静态代码块的作用是给类中的静态成员变量初始化赋值。
注意:在构造器中给静态变量赋值,并不能保证能赋值成功,因为构造器是在创建对象的时候才指向,但是静态变量可以不创建对象而直接使用类名来访问。
创建和初始化对象的过程
- 类加载,同时初始化类中的静态的属性
- 执行静态代码块
- 分配内存空间,同时初始化非静态的属性
- 调用类的父类构造器
- 对类中的属性进行显示赋值(有的话)
- 执行匿名代码块
- 执行构造器
- 返回内存地址
注:子类中非静态属性的显示赋值是在父类构造器执行完之后和子类中的匿名代码块执行之前的时候
静态导入
静态导包就是java包的静态导入,用import static代替import静态导入包是JDK1.5中的新特性。
意思是导入这个类里的静态方法。
这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(…);就可以将其写入一个静态方法print(…);再使用时直接print(…);就可以了。
但是这种方法建议在有很多重复调用的时候用,如果仅有一到两次调用,不如直接写来的方便。
import static java.lang.Math.random;
import static java.lang.Math.PI;
pulic class Item{
public static void main(String[] args){
//不静态导入,是需要Math.random()来调用的
System.out.println(random());
System.out.println(PI);
}
}
final修饰符
修饰类
用final修饰的类不能被继承,没有子类。我们可以用来修饰自己要定义的类。
修饰方法
用final修饰的方法可以被继承,但是不能被子类重写,可以用来修饰方法。
修饰变量
用final修饰的变量表示常量,只能被赋一次值。
被final修饰的变量也就是常量了,因为值不允许再被改变。
abstract修饰符
abstract可以用来修饰方法和类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类
抽象类中可以没有抽象方法,但是有抽象方法的类必须是抽象类。
语法
public abstract class Action{
public abstract void doSomething();//方法的声明
}
public void doSomething(){
...
//这部分是方法的实现,如果什么也没写,就叫方法的空实现
}
- 声明类的同时,加上abstract修饰符就是抽象类
- 声明方法的同时,加上abstract修饰符,并且去掉方法的大括号,同时结尾加上分号,该方法就是抽象方法。
用途
- 抽象类,不能使用new关键字来创建对象,也就是不能被实例化,它是用来让子类继承的
- 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
注意:子类继承抽象类后,需要实现抽象类中没有实现的抽象方法,否则这个子类也要声明为抽象类。