`

不要在构造器中调用可覆写的方法

 
阅读更多

        首先看一下下面的程序,猜猜会输出什么:

class Point{
  Point(){
     show();
  }
   void show(){
      System.out.println("Father.");
   }
}
class ColorPoint extends Point{
   void show(){
      System.out.println("Son.");
   }

  public static void main(String args[]){
       ColorPoint point=new ColorPoint();
   }

}

 由于,在子类的构造函数中会默认的调用父类的构造函数,但是父类的构造函数调用了被子类重载过得方法。这会导致直接调用子类覆盖后的方法。

所以输出结果:

Son.

 

     看懂了上面的代码,再分析分析下面的代码:

class Point{
	protected final int x,y;
	private final String name;
	Point(int x,int y){
		this.x=x;
		this.y=y;
		name=makeName();
	}
	protected String makeName(){
		return "["+x+","+y+"]";
	}
	public final String toString(){
		return name;
	}
}

public  class ColorPoint extends Point{
	
	private final String color;
	public ColorPoint(int x,int y,String color) {
		// TODO Auto-generated constructor stub
		super(x, y);
		this.color=color;
	}
	protected String makeName(){
		return super.makeName()+":"+color;
	}
	
	public static void main(String args[]){
		
		
		System.out.println(new ColorPoint(4, 2, "purple"));
	}
}

 当在父类中调用makeName()方法时,由于该方法已经被子类重写过了。所以直接调用的是子类的makeName()方法。由于此时导致color域还没有被赋值还是null,导致name已将变成了[4,2]:null。执行到

this.color=color;时虽然color域被赋值但是已经无法改变name域的值。所以输出了:

[4,2]:null

分享到:
评论

相关推荐

    16.方法调用1

    静态方法、私有方法、实例构造器和父类方法属于这一类,它们的调用版本在运行期不会改变。 - **分派调用** - 根据参数类型和接收者类型来确定方法版本。根据分派依据,分派可以是静态的(只依赖静态类型)或动态的...

    详解java重载与覆写的区别

    4. **构造方法**:构造方法不能被覆写,但可以有同名的构造方法来实现构造器的重载。 5. **抽象方法**:在抽象类中定义的抽象方法可以被子类覆写,并提供具体的实现。 理解并熟练掌握重载和覆写是Java程序员的基本...

    JAVA复习题+答案.pdf

    7. **super关键字**:在子类构造方法中,使用`super`调用父类的构造方法,这通常是子类构造方法的第一条语句。 8. **父类构造方法调用**:子类构造方法的第一条语句必须是调用父类的构造方法,要么通过`super`,...

    java学习笔记(二)

    在构造器中,`this()`可以用来调用同一类的其他构造器,但必须位于构造器的第一行。方法的重载意味着在同一个类中可以有多个同名方法,只要它们的参数列表不同。 面向对象的第二个特性是继承,使用`extends`关键字...

    Java Object原理图

    3. 对象构造器:在Java中,构造器(Constructor)用于初始化新创建的对象。当创建一个对象时,会调用对应的构造器来设置初始状态。构造器可以是默认的,也可以是用户自定义的,通过`this()`或`super()`调用来实现对...

    java学习笔记 java学习笔记

    `super`关键字用于子类中调用父类的构造器、普通方法和属性。子类构造器的第一行必须是`super()`或`super(参数列表)`,以调用父类的构造器。 4. **`final`关键字**: - `final`修饰的类不能被继承。 - `final`...

    C#基础面试题_2.pdf

    15. **构造函数**:当定义了一个带参数的构造函数后,需手动添加无参数构造函数,因为C#不再提供默认构造器。 16. **所有对象的基类**:C#中所有类都继承自`System.Object`。 17. **virtual关键字**:表示一个方法...

    C#面试题,C#面试题

    在面试中,C#的知识点涵盖广泛,包括语法、类与对象、继承、接口、抽象类、访问修饰符、方法重载与覆写等多个方面。下面我们将深入探讨这些核心概念。 1. **属性访问器**:在C#中,属性(Property)是封装数据的一...

    C#使用中常见问题整理

    `static readonly`则是在运行时初始化的只读字段,虽然同样不可更改,但其值可以在构造函数或字段初始化器中设置,提供了更多的灵活性。 ### 3. extern是什么意思? `extern`关键字用于声明一个外部函数或方法,这...

    android-service

    - 必须在构造方法中调用`super("worker_thread_name")`,指定工作线程的名称。 - 覆写`onHandleIntent()`方法处理具体任务,此方法在工作线程中运行。 - 覆写其他回调方法时,务必调用父类的实现以维持正常运行。 #...

    C#面试题,C#面试经典题

    10. 在方法定义中,virtual有什么含意? 答案:被virtual修饰的方法可以被子类覆写。 11. 能够将非静态的方法覆写成静态方法么? 答案:不能,覆写方法的签名必须与被覆写方法的签名保持一致,除了将virtual改为...

    C#与.NET技术平台实战演练.part2

    initializer10-5初始化只读数据10-6在构造器中使用out与ref10-7struct构造器10-7-1struct构造器的限制10-8static构造器10-8-1使用static构造器初始化静态成员10-8-2static构造器的限制10-9对象与内存10-9-l对象的...

    C#与.NET技术平台实战演练.part1

    initializer10-5初始化只读数据10-6在构造器中使用out与ref10-7struct构造器10-7-1struct构造器的限制10-8static构造器10-8-1使用static构造器初始化静态成员10-8-2static构造器的限制10-9对象与内存10-9-l对象的...

    精品(2021-2022年)资料软件开发c#.doc

    以上就是C#编程基础与特性的详细解释,涵盖了属性、继承、访问修饰符、构造函数、基类、方法重载和覆写、抽象类和接口、常量与只读字段、字符串、类与结构的区别,以及委托和事件处理等关键知识点。

    RecyclerView添加header

    3. 在Adapter的构造函数中,接收一个Header的View实例,调用`addHeader(View headerView)`方法将其添加到列表的开头。 4. 覆写`getItemCount()`方法,返回数据项数量加上1(Header)。 5. 覆写`onCreateViewHolder...

    Java面试宝典新人版

    抽象类可以包含字段、构造器、方法(包括抽象方法和非抽象方法);接口只能包含常量和抽象方法,不能有构造器和字段。 这些知识点只是Java面试中的一部分,全面准备面试还需要深入理解类加载机制、集合框架、异常...

    通过Lombok来简化你的代码1

    10. @Builder:用在类、构造器、方法上,为你提供复杂的builder APIs,让你可以像如下方式一样调用 Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction")....

    Spring Bean Lifecycle Control

    2. **依赖注入**:Spring会根据Bean定义中的属性和构造器参数,将依赖注入到Bean实例中。这可以通过`@Autowired`、`@Value`等注解实现,或者通过XML配置文件中的`<property>`标签来设置。 3. **容器回调**:在Bean...

Global site tag (gtag.js) - Google Analytics