1、代码块:
构造代码块:类中方法外,每创建一次对象就会执行一次,优先于构造函数执行
静态代码块:类中方法外,随着类加载而加载,且只执行一次,用来给类进行初始化,一般用来加载驱动静态代码块优先于主方法执行
主方法静态代码块 > 主方法 > 下一级类的静态构造方法(无论创建多少对象,只运行一次) > 构造代码块(创建一次对象就会执行一次)> 构造方法
public class LongTest {
static {
System.out.println("这是主方法的静态代码块!");
}
public static void main(String[] args) {
{
System.out.println("这是主方法代码块!");
}
Student st1 = new Student();
Student st2 = new Student("pingan",23);
}
}
class Student{
static {
System.out.println("这是下一级类的的静态代码块!");
}
{
System.out.println("这是下一级类的构造代码块!");
}
String name;
int age;
public Student() {
{
System.out.println("这是无参构造函数!");
}
}
public Student(String name,int age) {
this.age = age;
this.name = name;
{
System.out.println("这是有参构造函数!");
}
}
public void study() {
System.out.println("这是下一级类的方法");
}
}
运行结果如下:
2、继承(extends):
- java只支持单继承,不支持多继承
- 子类只能继承父类多有非私有成员(成员方法和变量)
- 子类不能继承父类的构造方法(类名都不一样),但是可以通过super区访问父类构造方法
- 子类中的变量名和父类一样,就近原则(但是一般不会这么弄,因为没有意义)
- this也可以调用父类的,在子类没有这个成员变量的时候
子类中所有的构造方法都会默认访问父类的空参构造方法,因为子类初始化前一定会先完成父类数据的初始化,其实是省略了一个super();的语句
如果父类只有有参构造,没有无参构造怎么办?
在子类的有参构造里加super(name,age);
在无参里直接super(“张三”,23);(转到了父类的有参构造中,值写死了,没意义)
或者this(“张三”,23)走子类的有参构造,子类再调到父类的有参构造
(注:二者只能取其一)
多重继承,每一个父类的默认构造函数都被执行了!
public class LongTest {
public static void main(String[] args) {
EZ ez = new EZ();
}
}
class YY{
public YY() {
System.out.println("this is yy");
}
}
class BB extends YY{
public BB() {
System.out.println("this is BB");
}
}
class EZ extends BB{
super(); %这个语句默认被省略了!
public EZ() {
System.out.println("this is EZ");
}
}
各种代码块的加载关系:
BB bb = new BB();
- 首先,方法区先把static静态区加载了,然后主函数也加载(毕竟主函数也是static修饰的),然后父类和子类的静态区块相继加载
- 然后堆中new了一个子类的构造函数,先==super()==调用父类的构造函数
- 发现父类的构造函数前面有个静态编码块啊,得,先把静态编码快加载咯
- 然后加载父类得构造函数
- 加载子类得构造函数,发现前面也有个构造代码块,也先加载
- 最后如果有类得方法调用,再加上方法。
public class LongTest {
static { System.out.println("这是最大boss的静态代码块,第-1个加载");}
public static void main(String[] args) {
{System.out.println("这是主函数的构造代码块,第0个加载");}
BB bb = new BB();
bb.study();
}
}
class YY{
static { System.out.println("这是父类静态代码块,第一个加载");}
{System.out.println("这是父类构造代码块,第三个加载");}
public YY() {
System.out.println("这是父类构造方法,第四个加载");
}
}
class BB extends YY{
static { System.out.println("这是子类静态代码块,第二个加载");}
{System.out.println("这是子类构造代码块,第五个加载");}
public BB() {
System.out.println("这是子类构造方法,第六个加载");
}
public void study() {
System.out.println("这是类中的方法,最后一个执行");
}
}
输出:
子类重写父类方法要求:
- 访问权限不能更低(最好一致)
- 不能重写父类得private方法
- 父类静态方法,子类也必须写成静态方法