我正在开发一个项目,用户正在为动物输入值(名称,年龄,性别等),用户输入的值显示在列表框中 这些类相互继承。以下是继承的工作原理:
Animal 类是所有类的父级。
哺乳动物类继承自 Animal 类。
Dog 类继承自 Mammal 类。
Cat 类继承自 Mammal 类
Reptile 类继承自 Animal 类
Snake 类继承自 Reptile 类
Lizard 类继承自 Reptile 类
Animal的变量是 id , name , age , gender 。
哺乳动物的变量是牙齿
Dog的变量是 barkLevel
用户可以选择要创建的动物。有一个列表框显示动物的类型(哺乳动物和爬行动物),旁边有一个列表框,根据用户选择的动物类型,它会显示动物。
例如,如果用户在列表框中选择 Mammal ,则旁边的列表框会显示 Dog 和 Cat 。
这是完美的,这不是问题。
问题:
输入值显示在结果列表中,但不显示在子类变量中。结果列表框 显示 ID ,名称,年龄,性别但不 牙齿或 barkLevel 。没有错误消息或任何内容。它只是不显示子类变量。
这是我的主要形式:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Assign_1
{
public partial class MainForm : Form
{
private Dog m_dog = new Dog();
private Cat m_cat = new Cat();
private Snake m_snake = new Snake();
private Lizard m_lizard = new Lizard();
private AnimalManager animalmgr = null;
private Animal m_animal = new Animal();
private Mammal m_mammal = new Mammal();
public MainForm()
{
//Visual Studio initializations
InitializeComponent();
//My initializations
InitializeGUI();
Gendercmb.DataSource = Enum.GetValues(typeof(GenderType));
Categorylst.DataSource = Enum.GetValues(typeof(Categorytype));
animalmgr = new AnimalManager();
}
private void InitializeGUI()
{
ReadInput();
}
private void ReadInput()
{
m_animal.Name = ReadName();
m_animal.Age = ReadAge();
m_mammal.Teeth = ReadTeeth();
m_dog.BarkLevel = ReadBarklevel();
m_animal.Gender = this.Gendercmb.GetItemText(this.Gendercmb.SelectedItem);
}
private int ReadAge()
{
int age = 0;
int.TryParse(Agetxt.Text, out age);
return age;
}
private int ReadBarklevel()
{
int bark = 0;
int.TryParse(barktxt.Text, out bark);
return bark;
}
private int ReadTeeth()
{
int teeth = 0;
int.TryParse(teethtxt.Text, out teeth);
return teeth;
}
private string ReadName()
{
string name = "";
name = Nametxt.Text;
return name;
}
private void addMammal(Mammal values)
{
ReadInput();
switch ((MammalType)Animallst.SelectedIndex)
{
case MammalType.Dog:
{
// Use a copy constructor to set a dog with common data
Dog m_dog = new Dog(values);
// If more data in GUI to fill in for this animal, do it here
//Then send it to the manager for adding to the list
animalmgr.add(m_dog);
break;
}
case MammalType.Cat:
{
Cat m_cat = new Cat(values);
animalmgr.add(m_cat);
break;
}
}
}
private void AddReptile(Reptile values)
{
ReadInput();
switch ((ReptileType)Animallst.SelectedIndex)
{
case ReptileType.Snake:
{
// Use a copy constructor to set a snake with common data
Snake m_snake = new Snake(values);
// If more data in GUI to fill in for this animal, do it here
//Then send it to the manager for adding to the list
animalmgr.add(m_snake);
break;
}
case ReptileType.Lizard:
{
Lizard m_lizard = new Lizard();
animalmgr.add(m_lizard);
break;
}
}
}
//When user clicks "Add to list"
private void button1_Click(object sender, EventArgs e)
{
ReadInput();
System.Windows.Forms.MessageBox.Show(m_dog.BarkLevel.ToString());
switch ((Categorytype)Categorylst.SelectedIndex)
{
case Categorytype.Mammal:
{
Mammal mammal = new Mammal(m_animal);
addMammal(mammal);
break;
}
case Categorytype.Reptile:
{
Reptile m_reptile = new Reptile(m_animal);
AddReptile(m_reptile);
break;
}
}
UpdateResults();
}
private void UpdateResults()
{
Resultlst.Items.Clear(); //Erase current list
//Get one elemnet at a time from manager, and call its
//ToString method for info - send to listbox
for (int index = 0; index < animalmgr.ElementCount; index++)
{
Animal animal = animalmgr.GetElementAtPosition(index);
toString method.
Resultlst.Items.Add(animal.ToString()); // <--- Here is the problem
}
}
}
}
这是我的动物经理班:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assign_1
{
class AnimalManager
{
// private List<Animal> m_animalList;
private List<Animal> m_animal;
private List<Mammal> m_mammal;
public AnimalManager()
{
//In this list objects off diff animals of all species are saved
// m_animalList = new List<Animal>();
m_animal = new List<Animal>();
m_mammal = new List<Mammal>();
}
public void add(Animal ObjIn)
{
m_animal.Add(ObjIn);
}
public bool IsIndexValid(int index)
{
return ((index >= 0) && (index < m_animal.Count));
}
public Animal GetElementAtPosition(int index)
{
//We choose to return a copy
if (IsIndexValid(index))
{
if (m_animal[index] is Mammal)
return new Mammal((Mammal)m_animal[index]);
if (m_animal[index] is Reptile)
return new Reptile((Reptile)m_animal[index]);
return null;
}
else
return null;
}
public int ElementCount
{
get { return m_animal.Count; }
}
}
}
更新
我现在知道问题是Resultlst.Items.Add(animal.ToString());
不知怎的,我需要包括哺乳动物和狗对象(取决于所选择的动物),但我不知道如何。
答案 0 :(得分:3)
据我所知,你从未真正归还你的子课程。假设你在m_animal
中拥有了所有的猫,狗,蛇和蜥蜴,当你通过基类构造函数运行它们时,你实际上正在丢失子类的属性。尝试直接返回对象:
public Animal GetElementAtPosition(int index)
{
if (IsIndexValid(index))
return m_animal[index];
else
return null;
}
如果您在所有课程中都覆盖了ToString()
,那么您应该得到您期望的结果。