欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

根据java 中的例子联想到的constructor ,父类,子类

程序员文章站 2022-07-14 16:16:49
...
[size=xx-large]例一:[/size]
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;
pt.shout();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
void haha(){
System.out.println("can creat a method here? No");
}
}
}

当按照上面的方法书写时,程序提示错误, 提示Syntax error on token(s), misplaced construct(s)
修改后如下:
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;

pt.shout();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
/* void haha(){
System.out.println("can creat a method here? No");
}*/
}
}

程序成功运行, 得到:age is 10
[size=xx-large]结论:[/size]constructor 有两个方面的特性:一是名字得和class 得名字一致,二是它是一种特殊的方法(因此具有一般方法的特性),特别之处在于它不会返回值。在java 里面, 方法是不可以嵌套创建的, 如果要在一个方法里面用到新的方法, 得通过call, 而不是直接建立一个新的方法在里面而产生像上面那样的错误。
[size=xx-large]例二:[/size]
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;
// pt.shout();

}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
thingsoutstatic();
}
}

能够成功运行,结果:method useful in constructor
[size=xx-large]结论:[/size]在constructor 里面, 我们能够去call 另一个方法, 当对象被创建时, 就会call constructor, constrctor 里面的任何属性(呵呵,这个属性好像是属于该class 的, 不是construcor单独拥有的,constructor 也是class 的属性呢!)都开始copy 到对象中,包括constructor 里面所call的方法, 简单一点说:constructor 是一种特殊的属性,在每次创建对象时, 就会将该类的属于promitive data type 的属性copy 到对象空间中,并在对象空间中创建一个reference的空间指向该constructor.
[size=xx-large]例三:[/size]
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;
// pt.shout();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
shout();
}
}

运行结果:age is 0
[size=xx-large]结论:[/size]如果方法在constructor 里面, 就是任何方法运行结果都回一模一样,值也不会有变化,而constructor 里涉及到的变量的值就会是class 属性, 而不是对象属性。要打印出变量属性, 得直接call shout() method.
[size=xx-large]例四:[/size]
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;
pt.shout();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}


public Pt(){
}
}

运行结果:age is 10
[size=xx-large]结论:[/size]对象现将类的值储存(此时已经从类的属性变成对象的属性了), 然后可以修改成自己单独拥有的值,从自己这里call 的方法当然是属于自己的,于是所使用的属性自然也是对象的属性了。(把constructor 当成一张设计图,class 想成构思,object 想成具体物体, 那么call constructor 时就是直接使用的这个构思的设计图, 而call object 得method 时, 该实现的方法也都得到实现了 , 当然得用object 自己的东西了)好难啰嗦清楚!!!
[size=xx-large]例五:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
System.out.println("super constructor");
}
}

class Pt1 extends Pt{
public Pt1(){
System.out.println("child constructor");
}
}

结果显示:
super constructor
child constructor
[size=xx-large]结论:[/size]每一个子类的对象创建都会先call 父类的构造器,然后在call 子类的构造器 (绝对不存在什么子类构造器覆盖父类构造器的问题哦,像一像,子类的产生本来就要有父类的构造器嘛,而且子类不就是根据父类来的吗?那么通知父类一声也是应该的, 呵呵,版权问题嘛!)
[size=xx-large]例六:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
System.out.println("super constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
public Pt1(int a){
System.out.println("child constructor");
}
}

结果显示:
super constructor
child constructor
[size=xx-large]结论:[/size]和子类constructor 的parameter无关,只要父类中存在super(), 而你在子类的构造器中没有特别去call 其他的super(int a)这种带parameter 的构造器,那么在产生子类对象时, 所调用的就是先call super(), 然后在子类。
[size=xx-large]例七:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
public Pt1(int a){
System.out.println("child constructor");
}
}

结果该程序不能运行,提示错误:Implicit super constructor Pt() is undefined. Must explicitly invoke another constructor
[size=xx-large]结论:[/size]如果在子类里没有call 父类的constructor, 那么它会自己去call super() 这个constructor, 此时父类里必须存在constructor.
[size=xx-large]例八:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
public Pt1(int a){
super(a);
System.out.println("child constructor");
}
}

结果显示:
super constructor 2
child constructor
[size=xx-large]结论:[/size]在没有default 得super()存在的情况下,必须在子constructor 中call 父类已经存在的constructor.
[size=xx-large]例九:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
public Pt1(int a){
super(int c);
System.out.println("child constructor");
}
}

程序错误, 提示Syntax error on token "int", delete this token, 但是一旦delete int 后,就会提示c cannot be resolved
[size=xx-large]结论:[/size]不要忘记了在java 中任何变量在使用前都得初始化(class 得properties 可以不用开始赋值,因为class 会自动初始化所有的properties, 但是你要初始化也是可以的), 在上面的例子九中,运行到super (int c )时, 程序发现c并没有值,所以程序报错。
[size=xx-large]例十:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
int c=0;
public Pt1(int a){
super(c);
System.out.println("child constructor");
}
}

程序出错, 提示Cannot refer to an instance field c while explicitly invoking a constructor
[size=large]可以修改为:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
static int c=0;
public Pt1(int a){
super(c);
System.out.println("child constructor");
}
}

为什么这里加上static 后程序就没有问题了?
[size=xx-large]猜测原因是:[/size]有constructor不一定表示创建了对象, (储存对象字段的空间和static 字段的空间是不相同的),而在constructor中指向instance data field 实例字段是不安全的, 因为这个实例 有可能根本就不存在, 而static 并不属于对象空间, 所以static可行。
本文转载自-和讯博客-Robin's Blog-ousys