You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#继承问题:Grua类ToString()未正确显示父类Camiones的Dominio属性

问题分析

你遇到的问题其实源于两个常见的C#继承误区:

1. 混淆了类继承和实例属性值的关系

继承是类层面的特性——Grua类继承了Camiones类的属性定义(Marca、Dominio),但每个实例的属性值是完全独立的!你创建的nuevoCamion(Camiones实例)和nuevaGrua(Grua实例)是两个毫无关联的对象,nuevaGrua不会自动继承nuevoCamion的Marca或Dominio值,必须手动给它赋值。

2. 可能在Grua类中重复定义了Marca属性(隐藏父类属性)

如果你的Grua类里重新声明了Marca属性(比如写了public string Marca { get; set; }),这会隐藏父类Camiones的Marca属性:你给nuevaGrua.Marca赋值时,实际操作的是子类自己的Marca,而父类的Marca还是默认的null。不过根据你的描述,Marca显示的是Grua设置的值,更可能是你没有重复定义属性,但误解了实例属性的独立性。


解决方案

步骤1:修正类的定义(避免隐藏父类属性)

确保Grua类不重复定义父类已有的属性,直接继承使用父类的属性:

// 抽象基类
public abstract class Equipos
{
    public abstract override string ToString();
}

// 父类Camiones
public class Camiones : Equipos
{
    // 父类的属性,子类Grua直接继承使用
    public string Marca { get; set; }
    public string Dominio { get; set; }

    public override string ToString()
    {
        return $"Camión: Marca={Marca}, Dominio={Dominio}";
    }
}

// 子类Grua,正确继承Camiones
public class Grua : Camiones
{
    // 只定义子类独有的属性
    public decimal Peso { get; set; }
    public int Altura { get; set; }
    public decimal PrecioHora { get; set; }

    // 正确调用父类ToString方法,再追加子类属性
    public override string ToString()
    {
        return $"{base.ToString()}, Peso={Peso}kg, Altura={Altura}m, Precio/hora={PrecioHora:C}";
    }
}

步骤2:正确初始化Grua实例的属性

如果你希望Grua实例的Dominio有值,必须显式给它赋值(因为它和Camiones实例nuevoCamion是独立对象):

// Camiones实例正常使用
var nuevoCamion = new Camiones
{
    Marca = "Volvo",
    Dominio = "ABC-123"
};
Console.WriteLine(nuevoCamion.ToString()); 
// 输出:Camión: Marca=Volvo, Dominio=ABC-123

// Grua实例,显式设置父类属性和子类属性
var nuevaGrua = new Grua
{
    Marca = "Mercedes", // 这里赋值的是继承自Camiones的Marca属性
    Dominio = "XYZ-789", // 必须显式设置Dominio,否则会为空
    Peso = 15000,
    Altura = 25,
    PrecioHora = 120.5m
};
Console.WriteLine(nuevaGrua.ToString()); 
// 输出:Camión: Marca=Mercedes, Dominio=XYZ-789, Peso=15000kg, Altura=25m, Precio/hora=$120.50

(可选)通过构造函数简化属性初始化

如果想避免忘记设置父类属性,可以给Camiones添加构造函数,让Grua调用父类构造函数来初始化继承的属性:

// 给Camiones添加构造函数
public class Camiones : Equipos
{
    public string Marca { get; set; }
    public string Dominio { get; set; }

    // 带参数的构造函数,强制初始化核心属性
    public Camiones(string marca, string dominio)
    {
        Marca = marca;
        Dominio = dominio;
    }

    // 保留无参构造(如果需要创建未初始化的实例)
    public Camiones() { }

    public override string ToString()
    {
        return $"Camión: Marca={Marca}, Dominio={Dominio}";
    }
}

// Grua的构造函数调用父类构造
public class Grua : Camiones
{
    public decimal Peso { get; set; }
    public int Altura { get; set; }
    public decimal PrecioHora { get; set; }

    public Grua(string marca, string dominio, decimal peso, int altura, decimal precioHora) 
        : base(marca, dominio) // 调用父类构造函数初始化Marca和Dominio
    {
        Peso = peso;
        Altura = altura;
        PrecioHora = precioHora;
    }

    public override string ToString()
    {
        return $"{base.ToString()}, Peso={Peso}kg, Altura={Altura}m, Precio/hora={PrecioHora:C}";
    }
}

// 使用时必须传入父类属性,避免遗漏
var nuevaGrua = new Grua("Mercedes", "XYZ-789", 15000, 25, 120.5m);

关键总结

  • 继承是类的定义层面的复用,不是实例属性值的复用,每个对象的属性值都是独立的。
  • 子类不要重复定义父类已有的属性,否则会隐藏父类属性,导致逻辑混乱。
  • 如果需要子类实例拥有父类属性的特定值,必须显式赋值(或通过构造函数强制传入)。

内容的提问来源于stack exchange,提问作者le0nicolas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 09:42:51