Переопределение классов
От: busk  
Дата: 26.04.22 16:34
Оценка:
Есть класс
Самолет

у него есть свойство
Тип салона

и есть Метод
УборкаСалона

в коде это выглядит так.

Хотелось бы в классах CargoSalonCleaner и MilitarySalonCleaner в качестве параметров для метода Clean иметь уже конкретный тип салона а не делать кастинг из SalonType

abstract class Aircraft
{
   abstract SalonType Salon { get; set; }
}

abstract class SalonType { }

SalonCargoType : SalonType { }

MilitaryCargoType : SalonType { }



abstract SalonCleaner
{
  abstract void Clean(SalonType salon);
}

CargoSalonCleaner : SalonCleaner
{
  void Clean(SalonCargoType  salon)
   {

   }  
}

MilitarySalonCleaner : SalonCleaner
{
  void Clean(MilitaryCargoType  salon)
   {

   }  
}
Re: Переопределение классов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.04.22 16:50
Оценка: +1
Здравствуйте, busk, Вы писали:

B>Хотелось бы в классах CargoSalonCleaner и MilitarySalonCleaner в качестве параметров для метода Clean иметь уже конкретный тип салона а не делать кастинг из SalonType

А в чем тогда смысл абстрактного метода Clean?
Отредактировано 26.04.2022 16:50 gandjustas . Предыдущая версия .
Re: Переопределение классов
От: Ночной Смотрящий Россия  
Дата: 26.04.22 18:43
Оценка:
Здравствуйте, busk, Вы писали:

B>Хотелось бы в классах CargoSalonCleaner и MilitarySalonCleaner в качестве параметров для метода Clean иметь уже конкретный тип салона а не делать кастинг из SalonType


switch (aircraft.SalonType)
{
  case SalonCargoType cargo:
    CleanCargo(cargo);
    break;
    
  case MilitaryCargoType military:
    CleanMilitary(military);
    break;
    
  default: ...
}
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Переопределение классов
От: romangr Россия  
Дата: 27.04.22 05:53
Оценка:
Здравствуйте, busk, Вы писали:

B>Есть класс

B>Самолет

B>у него есть свойство

B>Тип салона

B>и есть Метод

B>УборкаСалона

Как-то так можно:
    public abstract class Aircraft
    {
        public abstract SalonType Salon { get; set; }
    }

    public abstract class SalonType { }

    public class SalonCargoType : SalonType { }

    public class MilitaryCargoType : SalonType { }


    public abstract class SalonCleaner<T> where T : SalonType
    {
        public abstract void Clean(T salon);
    }

    public class CargoSalonCleaner : SalonCleaner<SalonCargoType>
    {
        public override void Clean(SalonCargoType salon)
        {
        }
    }

    public class MilitarySalonCleaner : SalonCleaner<MilitaryCargoType>
    {
        public override void Clean(MilitaryCargoType salon)
        {
        }
    }
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re: Переопределение классов
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.04.22 15:57
Оценка: 35 (1)
Здравствуйте, busk, Вы писали:

B>Есть класс

B>Самолет

B>у него есть свойство

B>Тип салона

B>и есть Метод

B>УборкаСалона

B>в коде это выглядит так.


B>Хотелось бы в классах CargoSalonCleaner и MilitarySalonCleaner в качестве параметров для метода Clean иметь уже конкретный тип салона а не делать кастинг из SalonType


B>
B>abstract class Aircraft
B>{
B>   abstract SalonType Salon { get; set; }
B>}

B>abstract class SalonType { }

B>SalonCargoType : SalonType { }

B>MilitaryCargoType : SalonType { }



B>abstract SalonCleaner
B>{
B>  abstract void Clean(SalonType salon);
B>}

B>CargoSalonCleaner : SalonCleaner
B>{
B>  void Clean(SalonCargoType  salon)
B>   {

B>   }  
B>}

B>MilitarySalonCleaner : SalonCleaner
B>{
B>  void Clean(MilitaryCargoType  salon)
B>   {

B>   }  
B>}
B>


public abstract class Aircraft<T> where T: SalonType
{
  public abstract T Salon {get;set;}
}

public abstract class SalonCleaner<T> where T: SalonType
{
  public abstract void Clean(T salon);
}

CargoSalonCleaner : SalonCleaner<SalonCargoType>
{
  override public void Clean(SalonCargoType salon)
  {

  }  
}

MilitarySalonCleaner : SalonCleaner<MilitaryCargoType>
{
  override public void Clean(MilitaryCargoType  salon)
  {

  }  
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Переопределение классов
От: -n1l-  
Дата: 29.04.22 20:57
Оценка: 8 (1)
Здравствуйте, busk, Вы писали:

B>Есть класс

B>Самолет

B>...

Это первый вариант, в лоб:

    abstract class SalonType { }
    class SalonCargoType : SalonType { }
    class MilitaryCargoType : SalonType { }

    abstract class Aircraft<TSalonType> where TSalonType : SalonType
    {
        public abstract TSalonType Salon { get; set; }
        public abstract void Clean(SalonCleaner<TSalonType> cleaner);
    }

    abstract class SalonCleaner<TSalonType> where TSalonType : SalonType
    {
        public abstract void Clean(TSalonType salon);
    }

    class CargoSalonCleaner : SalonCleaner<SalonCargoType>
    {
        public override void Clean(SalonCargoType salon)
        {
        }
    }
    class MilitarySalonCleaner : SalonCleaner<MilitaryCargoType>
    {
        public override void Clean(MilitaryCargoType salon)
        {
        }
    }


но можно сделать интереснее с контрвариантностью, если в клинере у нас не используется какая-то специфичная логика типов салона(я для этого предпосылок не вижу):


using System;

public abstract class SalonType { }
public class SalonCargoType : SalonType { }
public class MilitaryCargoType : SalonType { }

public abstract class Aircraft<TSalonType> where TSalonType : SalonType {
  public abstract TSalonType Salon { get; set; }
  public abstract void Clean(ISalonCleaner<TSalonType> cleaner);
}

public interface ISalonCleaner<in TSalonType> where TSalonType : SalonType {
  void Clean(TSalonType salon);
}

public class SalonCleaner : ISalonCleaner<SalonType> {
  public void Clean(SalonType salon) {
    Console.WriteLine(salon.GetType());
  }
}

public class MilitaryAircraft : Aircraft<MilitaryCargoType> {
  public MilitaryAircraft() {
    Salon = new MilitaryCargoType();
  }
  public override MilitaryCargoType Salon { get; set; }
  public override void Clean(ISalonCleaner<MilitaryCargoType> cleaner) {
    cleaner.Clean(Salon);
  }
}

public class SalonAircraft : Aircraft<SalonCargoType> {
  public SalonAircraft() {
    Salon = new SalonCargoType();
  }
  public override SalonCargoType Salon { get; set; }
  public override void Clean(ISalonCleaner<SalonCargoType> cleaner) {
    cleaner.Clean(Salon);
  }
}

class Program {
  public static void Main (string[] args) {
  var calonCleaner = new SalonCleaner();
  var militaryAircraft = new MilitaryAircraft();
  var salonAircraft = new SalonAircraft();

  militaryAircraft.Clean(calonCleaner);
  salonAircraft.Clean(calonCleaner);
  }
}

выведет:

MilitaryCargoType
SalonCargoType


В этом случае нам не придется писать еще 2 доп класса для клинера если вдруг алгоритм чистки изменится для каких-то частей системы.
Достаточно будет написать еще один клинер и использовать в коде:
...

public class FormattedOuputSalonCleaner : ISalonCleaner<SalonType> {
  public void Clean(SalonType salon) {
    Console.WriteLine($"The type of salon is: '{salon.GetType()}'");
  }
}

...

class Program {
  public static void Main (string[] args) {
    var newCleaner = new FormattedOuputSalonCleaner();
    var calonCleaner = new SalonCleaner();
    var militaryAircraft = new MilitaryAircraft();
    var salonAircraft = new SalonAircraft();
  
    militaryAircraft.Clean(calonCleaner);
    salonAircraft.Clean(calonCleaner);
    militaryAircraft.Clean(newCleaner);
    salonAircraft.Clean(newCleaner);
  }
}

выведет:

MilitaryCargoType
SalonCargoType
The type of salon is: 'MilitaryCargoType'
The type of salon is: 'SalonCargoType'
Re: Переопределение классов
От: Mr.Delphist  
Дата: 05.05.22 06:59
Оценка:
Здравствуйте, busk, Вы писали:

Вот тут — нарушение ООП, LSP и прочих троебуквий

B>CargoSalonCleaner : SalonCleaner

B>{
B> void Clean(SalonCargoType salon)
B> {

B> }

B>}

B>MilitarySalonCleaner : SalonCleaner

B>{
B> void Clean(MilitaryCargoType salon)
B> {

B> }

B>}
B>[/cs]

Есть серьёзные сомнения, что подобное наследование реально нужно: CargoSalonCleaner и MilitarySalonCleaner
В общем, ещё разок пролистать книжку GoF про паттерны проектирования.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.