java中父类与子类, 不同的两个类中的因为构造函数由于递归调用导致栈溢出问题

  1 /*
  2 对于类中对成员变量的初始化和代码块中的代码全部都挪到了构造函数中,
  3 并且是按照java源文件的初始化顺序依次对成员变量进行初始化的,而原构造函数中的代码则移到了构造函数的最后执行
  4 */
  5 import static java.lang.System.out;
  6
  7 public class PersonDemo
  8 {
  9     public static void main(String[] args)
 10     {
 11          //*********测试父类与子类之间的循环调用的问题
 12         out.println("main1");
 13
 14         Father f = new Father();
 15
 16         out.println("main2");
 17
 18         f.show();
 19
 20         out.println("main3");
 21
 22         //*********测试两个无关类的循环调用的问题
 23
 24                 MyClass11 m1=new MyClass11();
 25             m1.myOut();
 26     }
 27 }
 28
 29 class Father
 30 {
 31     public Son s ; //=new Son();
 32
 33         /*
 34               public Song s= new Son(), 注意在这里进行初始化操作相当于在构造函数中进行初始化,会导致栈溢出, why?
 35               在主函数中我们产生了一个Father对象, 然后在new一个Son对象的过程中,Son对象调用其父类的构造方法来完成
 36               一些子类中包含父类成员的初始化,最终导致了循环调用,最终栈溢出
 37         */
 38     public newSon ns =null; // new newSon();
 39
 40     public Father()
 41     {
 42         this(10);
 43         System.out.println("Father");
 44     }
 45
 46     public Father(int a)
 47     {
 48         //this();很显然, 加上这一句就会形成构造函数递归调用!哈哈。。。
 49     }
 50
 51     public void show()
 52     {
 53         s = new Son();
 54                 /*
 55               如果我们将 s 的赋值操作放在这里, 也就是去掉 public Son s = new Son()的初始化,这样就不会导致栈溢出了
 56                     看一看也就会明白了, new Son()时会调用父类Father的构造方法来完成Son的一些成员的初始化,但是其父类构造
 57                     函数中没有行循环调用!
 58                 */
 59         ns = new newSon();
 60
 61         System.out.println("father show");
 62
 63         s.show();
 64         ns.show();
 65     }
 66
 67     public class newSon extends Father//内部类同样会导致上面的问题!
 68     {
 69         public newSon()
 70         {
 71             System.out.println("newSon");
 72         }
 73
 74         public void show()
 75         {
 76             System.out.println("newSon show");
 77         }
 78     }
 79 }
 80
 81 class Son extends Father
 82 {
 83     public int a = 20;
 84
 85     public Son()
 86     {
 87         super();
 88         System.out.println("Son");
 89     }
 90
 91     public void show()
 92     {
 93         System.out.println("Son show");
 94     }
 95 }
 96
 97 class MyClass11{
 98
 99     MyClass22 m2;
100    //MyClass22 m2=new MyClass22();//这样写会导致循环调用问题
101
102    public MyClass11(){
103        //m2=new MyClass22();//这样写和上面的错误是一样的
104    }
105    public void show(){
106       System.out.println("This MyClass11");
107    }
108    public void myOut(){
109        m2=new MyClass22();//m2的赋值放在这里
110        m2.show();
111    }
112 }
113
114 class MyClass22{
115
116    MyClass11 m1;
117    public MyClass22(){
118        m1=new MyClass11();//移位main()函数中没有定义MyClass22的对象,所以这句赋值不会导致循环调用的问题,只需要将MyClass11中的赋值操作更改一下就好了
119    }
120    public void show(){
121       System.out.println("This MyClass22");
122    }
123    public void myOut(){
124        m1.show();
125    }
126 }

java中父类与子类, 不同的两个类中的因为构造函数由于递归调用导致栈溢出问题

时间: 2024-12-21 04:21:55

java中父类与子类, 不同的两个类中的因为构造函数由于递归调用导致栈溢出问题的相关文章

java中父类与子类的关系以及使用

java中父类与子类的关系以及使用 在java中规定:一个父类可以有多个子类,但是一个子类只能有一个父类.子类可以通过extends关键字来继承父类.做个比较通俗的比喻,就像一个父亲可以有多个亲孩子,但是一个孩子只能有一个亲生父亲. 1.继承以及重写:子类继承父类是对父类属性和方法的全面继承,同时子类在继承了父类的方法后,可对父类的方法进行重写. public class Son extends Fat{ private int b; private String h1; public void

Java 多态 父类和子类方法的访问控制权限

Java 多态 父类和子类方法的访问控制权限 @author ixenos 父类和子类方法的访问控制权限 继承是为了扩展类的功能,而这种扩展显然就是对一个原始类的扩展,目的还是向上转型来调用,所以这就是一个对象多态的问题. 既然多态,那么访问控制权限就要让父类也能访问. 也就是说,子类重写方法时不能使该方法拥有比父类更严格的访问控制权限. 否则违背了多态,导致向上类型转换后,使用父类变量无法调用该子类私有方法.

AQS的子类在各个同步工具类中的使用情况

AQS AQS(AbstractQueuedSynchronizer)是 java.util.concurrent的基础.J.U.C中宣传的封装良好的同步工具类Semaphore.CountDownLatch.ReentrantLock.ReentrantReadWriteLock.FutureTask等虽然各自都有不同特征,但是简单看一下源码,每个类内部都包含一个如下的内部类定义: abstract static class Sync extends AbstractQueuedSynchro

Reader与InputStream两个类中的read()的区别

InputStream类的read()方法是从流里面取出一个字节,他的函数原型是 int read(); ,Reader类的read()方法则是从流里面取出一个字符(一个char),他的函数原型也是 int read(); . 我们都知道java使用的是UNICODE字符集,在java中字符和字符串都是使用UTF-16BE编码方式,即一个字符两个字节,在内存中高位在低字节,这也是BE的由来,BIG ENDIAN可以理解成大位的在开头,例如一个char的值是0XAC56,那么在内存中的形式就是AC

转载:C++中两个类中互相包含对方对象的指针问题

原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某一个类未定义...所以我就想啊想,这样也对,我的头文件都有#ifndef的,包含了一次就不能再包含了,以为就实现不了这样的功能,于是就改了设计方案: class A { public: A(B* pB):m_pB(pB) { } private: B* m_pB; }; class B { publ

条款十三: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同

template<class t> class array { public: array(int lowbound, int highbound); ... private: vector<t> data; // 数组数据存储在vector对象中 // 关于vector模板参见条款49 size_t size; // 数组中元素的数量 int lbound, hbound; // 下限,上限 }; template<class t> array<t>::a

3.Java继承中父类与子类的初始化顺序

在 Java 编程语言中,对象的初始化是非常结构化的,这样做是为了保证安全.在前面的模块中,看到了当一个特定对象被创建时发生了什么.由于继承性,对象被完成,而且下述行为按顺序发生: 存储空间被分配并初始化到 0 值 进行显式初始化 调用构造方法 层次中的每个类都会发生最后两个步骤,是从最上层开始. Java 技术安全模式要求在子类执行任何东西之前,描述父类的一个对象的各个方面都必须初始化.因此,Java 编程语言总是在执行子构造方法前调用父类构造方法的版本.有继承的类在运行的时候,一定要记得:初

Python中父类和子类间类属性(非实例属性)的设置获取的传递

前几天做一个项目,遇见类似这样一个问题.父类是个公用类,很多子项目中都运用到了,而子类也要作为一个基本类在该项目中的很多地方都要用到,但是的原始父类里面有些类属性(注意这里是类属性,不是实力属性).在程序运行时候要进行重新设置. 背景:Python中父类的类属性,类方法,实力属性都能够被子类继承,实力属性的再设置很简单,当然为了控制类属性的访问权限(Python中不能完全实现控制),也可以用@preproty装饰符优化和控制实力属性的设置,父类的类属性被子类继承,可以很容易的获得父类属性的内容,

【Java知识点专项练习】之 数据类型两大类

Java的数据类型分为两大类:基本类型和引用类型: 基本类型只能保存一些常量数据,引用类型除了可以保存数据,还能提供操作这些数据的功能: 为了操作基本类型的数据,java也对它们进行了封装, 得到八个类,就是java中的基本类型的封装类:他们分别是: 八种基本类型: byte short ?? int ? long float double ?? char ?? boolean 对应的包装类 : Byte Short Integer Long Float Double Character Boo