二、面对对象---4.
(一)代码块
159、字段不存在多态特征
class SuperClass
{
public String name = "Super.name";
public void doWork()
{
System.out.println("Super.doWork");
}
}
class SubClass extends SuperClass
{
public String name = "Sub.name";
public void doWork()
{
System.out.println("Sub.doWork");
}
}
//字段不存在多态特征
class FieldDemo
{
public static void main(String[] args)
{
SuperClass clz = new SubClass();
clz.doWork(); //Sub.doWork
System.out.println(clz.name); //??? Super.name
}
}
通过对象调用字段,在编译时期就已经决定了调用哪一块内存空间的数据。
字段不存在覆盖的概念,在多态时,不能有多态特征(在运行时期体现子类特征)。只有方法才有覆盖的概念。
当子类和父类存在相同的字段的时候,无论修饰符是什么(即使是private),都会在各自的内存空间中存储数据。
160.代码块语句
1)局部代码块:直接定义在方法内部的代码块
//代码块
class CodeBlockDemo
{
public static void main(String[] args)
{
{
//局部代码块
int age = 17;
System.out.println(age);
}
System.out.println(age); // 错误: 找不到符号
}
}
一般是不会直接使用代码块的,只不过我们会结合if,while,for,try等关键字联合,表示一块代码区域
if (true)
{
System.out.println("局部代码块");
}
2)初始化代码块(构造代码块):直接定义在类中。每次创建对象都会调用构造器,在调用构造器之前会先执行本类中的初始化代码块。
//代码块
class CodeBlockDemo
{
{
System.out.println("初始化代码块");
}
CodeBlockDemo()
{
System.out.println("构造器....");
}
public static void main(String[] args)
{
System.out.println("进入main方法");
//创建三个CodeBlockDemo对象
new CodeBlockDemo();
new CodeBlockDemo();
new CodeBlockDemo();
}
}
通过反编译发现,初始化代码块也作为构造器的最初的语句
一般不使用初始化代码块,即使要做初始化,一般也在构造器中做即可,如果初始化代码块比较多,此时构造器的结构比较混乱,此时专门定义一个方法做初始化操作,再在构造器中调用即可
3)静态代码块:使用static修饰的初始化代码块。特点:在主方法执行之前执行静态代码块,而且只执行一次。main方法是程序入口,为什么静态代码块优先于main方法执行。静态成员随着字节码的加载也加载进JVM,此时main方法还未执行,因为方法需要JVM调用,先把字节码加载进JVM,而后JVM再调用main方法。一般用来做初始化操作,加载资源,加载配置文件等。
成员+static:属于类
成员不加static:属于对象
//不写主方法,打印Hello World!
class CodeBlockDemo1
{
static
{
System.out.println("Hello World!");
}
public static void main(String[] args)
{
}
}
161、面试题-代码执行顺序
//面试题,分析下面代码的运行顺序
/*输出结果:
1)1 :App类依赖于SubClass类,所以得先把SubClass类的字节码加载进JVM
2)构造SuperClass :
3)2
4)4
5)3
6)Hello
*/
public class App
{
private static App d = new App(); //static字段的初始化,静态的成员在底层通过静态代码块做初始化,相当于private static App d = null;
private SubClass t = new SubClass(); //非static字段的初始化都在当前类的构造器前面执行,非静态成员在底层是通过构造器做初始化,private SubClass t = null;
static
{
//d = new App();
System.out.println(3);
}
public App()
{
//t =new SubClass();
System.out.println(4);
}
public static void main(String[] args)
{
System.out.println("Hello");
}
}
//父类
class SuperClass
{
SuperClass()
{
System.out.println("构造SuperClass");
}
}
//子类
class SubClass extends SuperClass
{
static //静态代码块
{
System.out.print