Wiele pochodnych klas abstrakcyjnych?


Muszę stworzyć system zarządzania kursami z kategoriami kursów:
Cooking, sewing and writing courses

gotowanie
i
pisanie
mają po 2 kursy (włoski, owoce morza, kreatywne pisanie i pisanie biznesowe). Tworzy to pochodne streszczenie:
abstract course -> abstract cooking -> concrete seafood

Abstrakcyjne gotowanie i pisanie mają wspólne pola i niektóre typowe metody, jednak mają również metody abstrakcyjne, które są abstrakcyjne w klasie bazowej.
Czy można to zrobić w C #? Jeśli utworzę pochodne metody abstrakcyjne klasy abstrakcyjnej, program Visual Studio powie, że ukrywają abstrakcyjną klasę bazową, a następnie konkretne metody klasy mają błędy, mówiąc, że klasa podstawowa powinna być abstrakcyjna (jest, ale nie powinien się rejestrować). Szukałem odpowiedzi. Wiem, że pojedyncze dziedziczenie jest używane w C #, ale dziedziczenie idzie w dół łańcucha. Jaka jest najlepsza odpowiedź?
Oto fragment kodu - mam nadzieję, że rozwiąże to problem:
public abstract class Course
{
public abstract void AddStudent(StudentName sn, int f);
public abstract decimal CalculateIncome();
}public abstract class WritingCourse : Course
{
public void AddStudent(StudentName sn, int f)
{
//Add student
}
public abstract decimal CalculateIncome();// can only be claculated in concrete
}public class BusinessWritCourse : WritingCourse
{
public void AddStudent(StudentName sn, int f):
base(sn, false){} public decimal CalculateIncome()
{
return//do stuff
}
}public class SewingCourse : Course
{
public override void AddStudent(StudentName sn, int f)
{
//do stuff
} public override decimal CalculateIncome()
{
return//do stuff
}
}

Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

jeśli uczynię pochodne abstrakcyjnymi
klas, mówi abstrakcyjne studio wizualne
że ukrywają abstrakcyjną klasę bazową i
Następnie Metody klasy betonowej mają
błędy mówiące, że klasa bazowa powinna być
streszczenie (jest, ale nie powinno być zarejestrowane)

Jeśli masz podstawową klasę "A", która ma abstrakcyjną metodę "b ()", wówczas nie musisz deklarować "b ()" jako abstrakcyjny w b: A, aby C: B zastępuje go, po prostu nie Użyj go. Nawet jeśli zastąpisz metodę "B ()" w klasie B, możesz go zastąpić w klasie "C ()" (a nawet użyj podstawy. (); Wdrożyć B.
Jakiś kod:
public abstract class A{
public abstract void b();
}public class B : A{
public override void b() {//do stuff };//overrides b from a
public virtual void c() {//do stuff };//creates an implemented method c in B that can be overriden by childs.
public void d() {//do stuff};
}public class C : B{
public override void b() {//do stuff};//overrides b from A, works!
public override void c() {//do stuff};//overrides c from B, works!
public override void d() {//do stuff};//doesn't work since d from B isn't abstract or virtual (hides it)
public new void d() {//do stuff};//works, hides d, but when you use inheritance this method will not be called, instead B's d() method will be called, only if you see C as the specific class C this will work
}

Wyjaśnijmy też: metody zadeklarowane jako abstrakcyjne muszą zostać przesłonięte (tak jak w interfejsie i tylko bezpośredni potomek klasy, która deklaruje metodę abstrakcyjną). Metody zadeklarowane jako wirtualne można zastąpić, ale nie są one wymagane.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Myślę, że ten rodzaj problemu lepiej rozwiązać za pomocą interfejsów niż klas abstrakcyjnych:
Były:
//
interface IInterface1
{
void SameMethod();
}interface IInterface2
{
void SameMethod();
}
class TestClass : IInterface1, IInterface2
{
void IInterface1.SameMethod()
{
// do one thing for Interface 1
} void IInterface2.SameMethod()
{
// do something elsefor Interface 2
}
}class Program
{
static void Main(string[] args)
{
TestClass test = new TestClass(); IInterface1 i1 = test;
i1.SameMethod();// will call IInterface1.SameMethod() IInterface2 i2 = test;
i2.SameMethod();// will call IInterface2.SameMethod() }
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

public class StudentName
{ }public abstract class Course
{
public abstract void AddStudent(StudentName sn, int f);
public abstract decimal CalculateIncome();
}public abstract class WritingCourse : Course
{
override public void AddStudent(StudentName sn, int f)
{
//Add student
}
override public abstract decimal CalculateIncome();// can only be claculated in concrete
}public class BusinessWritCourse : WritingCourse
{
override public void AddStudent(StudentName sn, int f)
{ base.AddStudent(sn, 0); } override public decimal CalculateIncome()
{
return (decimal)3.4;//do stuff
}
}public class SewingCourse : Course
{
public override void AddStudent(StudentName sn, int f)
{
//do stuff
} public override decimal CalculateIncome()
{
return (decimal)10;//do stuff
}
}class Program
{
static void Main(string[] args)
{ }
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli dobrze rozumiem, myślę, że chciałbyś użyć słowa kluczowego „virtual” dla metod abstrakcyjnych, które chcesz zastąpić?
Jeśli mówisz o błędzie, który mówi coś w stylu „jakaś metoda ukrywa dziedziczonego członka, dodaj nowe słowo kluczowe, jeśli ukrywanie było zamierzone”, to wystarczy virtual w metodzie bazowej i nadpisanie odziedziczonej metody:
public abstract class BaseClass
{
public virtual void SomeMethod()
{
}
}
public abstract class InheritingClass : BaseClass
{
public override void SomeMethod()
{
}
}

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się