一.字段不存在多态特征
-
通过对象调用字段,在编译时期就已经决定了调用哪一块内存空间的数据。
字段不存在覆盖的概念,没有多态特征(在运行时期体现子类特征)。 -
只有实例方法有覆盖的概念
-
当子类和父类存在相同的字段的时候,无论修饰符是什么(即使private),都会在各自的内存空间存储
数据。
新建FeildDemo.java
//字段不存在多态特征
//父类
class SuperClass
{
public String name = "Super.name";
public void doWork(){
System.out.println("SuperClass.doWork");
}
}
//子类
class SubClass extends SuperClass
{
public String name = "SubClass";
public void doWork(){
System.out.println("SubClass.doWork");
}
}
class FieldDemo
{
public static void main(String[] args)
{
SuperClass sc = new SubClass();
sc.doWork();//SubClass.dowork
System.out.println(sc.name);//Super.name
}
}
二. 什么是代码块
在类或者在方法中,直接使用“{}”括起来的一段代码,表示一块代码区域。
代码块里变量属于局部变量,只在自己所在的区域(前后的{})内有效
三. 代码块的分类
- 根据代码块定义位置的不同,分为三种形式:
- 局部代码块:直接定义在方法内部的代码块。
一般的,不会直接使用局部代码块,要结合if,while等等连用。 - 初始化代码块(构造代码块):直接定义在类中。
每次创建对象的时候都会执行初始化代码块。 - 通过反编译之后,我们发现,初始化代码也作为构造器的最初的语句。
我们一般不使用初始化代码块,一般在构造器中做即可,如果初始化操作的代码比较多,
此时构造器的结构比较混乱,此时专门定义一个方法做初始化操作,再在构造器中调用即可。
- 静态代码块:使用static修饰的初始化代码块。
在主方法执行之前执行静态代码块,而且只执行一次。
静态成员随着字节码的加载进入JVM,此时main方法还没有执行,因为方法需要JVM调用。
先把字节码加载进JVM,而后JVM再调用main方法。
一般的,我们用来做初始化操作,加载资源,加载配置文件等。
- 局部代码块:直接定义在方法内部的代码块。
新建CodeBlockDemo.java
//代码块Demo
class CodeBlockDemo
{
{//初始化代码块
System.out.println("初始化代码块");
}
CodeBlockDemo(){
System.out.println("构造器代码块");
}
//静态代码块
static {
System.out.println("静态代码块");
}
public static void main(String[] args)
{
System.out.println("进入main方法");
{
//局部代码块
int age = 14;
System.out.println(age);
}
//System.out.println(age);//报错
if (true)
{
System.out.println("局部代码块");
}
new CodeBlockDemo();
new CodeBlockDemo();
}
}
四. 代码的执行顺序(面试)
新建APP.java
class APP
{
private static APP a = new APP();
private SubClass sc = new SubClass();//非静态代码块会在构造器里优先执行。
static{
System.out.println("4");
}
APP(){
System.out.println("3");
}
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
//父类
class SuperClass
{
SuperClass(){
System.out.println("父类的构造器");
}
}
//子类
class SubClass extends SuperClass
{
static{
System.out.println("1");
}
SubClass(){
System.out.println("2");
}
}
运行结果
- 1 因为APP依赖于SubClass,所以优先把SubClass字节码加载进JVM
- 父类的构造器 SubClass继承于SuperClass,所以SubClass构造器里有个隐式的super()
- 2
- 3 非静态代码块在构造器里优先执行。
- 4
- Hello World!