package com.hanwei.service;
class testParent{
public testParent(){
System.out.println("我是父类的无参数构造方法");
}
public testParent(String a){
System.out.println("我是父类的有参数的构造方法");
}
static{
System.out.println("我在父类静态块当中");
}
{
System.out.println("我在父类非静态块当中");
}
}
public class test extends testParent{
public test(){
//super("");
System.out.println("我是子类的无参数构造方法");
}
static{
System.out.println("我在子类静态块当中");
}
public test(String a){
System.out.println("我是子类的有参数的构造方法");
}
{
System.out.println("我在子类非静态块当中");
}
public static void main(String arsg[]){
new test();
}
}
对于上面的执行顺序
1.父类的静态块
2.子类静态块
3.父类的非静态块
4.父类的无参数构造方法
5.子类的非静态块
6.子类的无参数构造方法
如果我们是new test("1");来调用,那么前面1,2,3,4,5顺序也会一样,6会执行自己有参数构造方法。如果父类中有无参数构造方法,那么子类也会无条件先运行父类的构造方法,注意是调用不是继承,子类是不能继承父类的构造方法的。
情况如下
不过始终记住一句“如果父类中没有显式的写出无参数构造方法,只有带参数的构造器,那么在执行子类的相应构造方法之前一定会调用父类的带参数构造方法,否则都出出错”
1.父类中没有显式的构造器,子类构造方法执行之前也没有显式super调用父类的默认无参数构造器,那么它也会无条件调用父类中默认的无参数构造方法。
如下:
package com.hanwei.service;
class testParent{
}
public class test extends testParent{
public static int a=0;
public test(){
//其实这里是super调用了父类的无参数构造器
System.out.println("我是子类的无参数构造方法");
}
public static void main(String arsg[]){
new test();
System.out.println(test.a);
}
}
2.父类中只有带参数的构造器,没有显式无参数构造器,
子类中的构造方法执行之前也没有显式super调用父类的这个带参数构造器,那么无论怎么调用都是会出错,如下所示的几种情况都会出错
(1)
package com.hanwei.service;
class testParent{
public testParent(String a){
System.out.println("我是父类的有参数的构造方法");
}
}
public class test extends testParent{
public static int a=0;
public test(String a) {
// TODO Auto-generated constructor stub
}
public static void main(String arsg[]){
new testParent("");//子类中没有super调用父类(带参数)构造器
System.out.println(test.a);
}
}
(2)
package com.hanwei.service;
class testParent{
public testParent(String a){
System.out.println("我是父类的有参数的构造方法");
}
}
public class test extends testParent{
public static int a=0;
public test(){
System.out.println("我是子类的无参数构造方法");
}
public static void main(String arsg[]){
new test(); //子类无参数构造器中没有调用父类的带参构造器
System.out.println(test.a);
}
}
(3)
package com.hanwei.service;
class testParent{
public testParent(String a){
System.out.println("我是父类的有参数的构造方法");
}
}
public class test extends testParent{
public static int a=0;
public test(String a){
System.out.println("我是子类的无参数构造方法");
}
public static void main(String arsg[]){
new test("");
System.out.println(test.a);
}
}
换句话说只要子类有对象产生,那么一定会执行父类的一个构造方法。如果没有显式或者隐式调用那么它都会出错,由于显式super调用始终在子类构造方法的第一句,所以执行的父类的构造方法一定在子类之前。
如果子类构造器没有显式地调用父类的构造器,则将自动调用父类的默认(没有参数)的构造器。如果父类没有不带参数的构造器,并且在子类的构造器中又没有显式地调用父类的构造器,则java编译器将报告错误(除了父类中没有任何显式构造器的情况,这种其实也是有默认调用父类的默认(没有参数)的构造器)。
对象总是伴随这new产生,如果没有new那么直接如类名调用静态成员是没有对象产生的
子类不能继承父类的构造方法,如果子类有调用了父类的无参数构造器,那么就会创建一个父类对象,然后再加上自己拥有的成员变成了子类对象,既然有父类对象的产生,那么私有成员就是被继承了的,只是子类无法访问,比如常见的实体类中,子类可以通过get和set方法来访问和修改父类的成员变量,但是无法调用父类私有方法。私有车成员被隐藏了,但是子类的内存中时存在的,只是不能调用。
private修饰的成员子类有没有继承呢?。
来自百度的网友回答:
子类继承父类,子类拥有了父类的所有属性和方法。
程序验证,父类的私有属性和方法子类是无法直接访问的。当然私有属性可以通过public修饰的getter和setter方法访问到的,但是私有方法不行。
假设:子类不能够继承父类的私有属性和方法
那么:分析内存后,会发现,当一个子类被实例化的时候,默认会先调用父类的构造方法对父类进行初始化,即在内存中创建一个父类对象,然后再父类对象的外部放上子类独有的属性,两者合起来成为一个子类的对象。
所以:子类继承了父类的所有属性和方法或子类拥有父类的所有属性和方法是对的,只不过父类的私有属性和方法,子类是无法直接访问到的。即只是拥有,但是无法使用
下面总结文字概述来自:http://blog.csdn.net/u010442302/article/details/52052091
在java中,static可以修饰成员变量、成员方法、代码块、内部类。
- static修饰成员变量,可以达到全局变量的效果(Java没有全局变量的概念),当一个类定义了static变量,其实就是申请一个内存地址,所有该类的对象共享这个静态成员变量。
这里区分下:静态变量和实例变量。静态变量:用static修饰,属于类,只要类被加载就会被分配内存空间;实例变量:没有static修饰,只有对象被创建了,才会分配内存空间,每一个对象的实例变量互不相关,引用方式:只能对象.实例变量。
2.static修饰成员方法,static修饰的方法是类的方法,不需要创建对象就可以调用,而非静态方法,只有对象呗创建了,才可以调用方法。
静态方法不能使用this,super关键字,不能调用非static的成员变量,非static的成员方法,只能访问static修饰的成员变量,成员方法。因为没有static修饰的成员变量,成员方法,这个类的对象还没被创建,即使创建了也无法确定是哪个对象的。
3.static修饰代码块,会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法,具体见:http://blog.csdn.net/u010442302/article/details/51365857
4.static修饰内部类,这样可以不依赖与外部类实例对象而被实例化,而通常的内部类需要外部类实例化后才能实例化。静态内部类不能与外部类有相同的类名,不能访问外部类的成员变量,只能访问外部类的static成员变量和static方法(包括外部类的私有)。实例内部类格式:Outer.Inner name = new Outer.Innner();
Java初始化,加载顺序:父类静态成员变量与父类静态代码块(谁在前先调用谁,顺序加载),子类静态成员变量与子类静态代码块(谁在前先调用谁,顺序加载),父类非静态成员变量,父类非静态代码块,父类构造函数,子类非静态成员变量,子类非静态代码块,子类构造函数