Как извлечь из метода, если изменилось только имя? - PullRequest
2 голосов
/ 11 апреля 2020

Итак

У меня есть такой базовый класс:

 public abstract class Car
    {      

        protected static bool _on { get; set; }
        public abstract void Drive();
}

и такой производный класс:

 public class Renault: Car
    {      

        public override void Drive()
        {
            if (!_on)
            {
                Console.WriteLine("Drive renault");
            }
            else
            {
                Console.WriteLine("Have to start renault first");
            }
        }

и другой производный класс:

 public class Porsche :Car
    {
        public override void Drive()
        {            

            if (_on)
            {
                Console.WriteLine("Drive Porsche");
            }
            else
            {
                Console.WriteLine("Have to start Porsche first");
            }

        }      
    }

Но вы видите, что реализация метода почти такая же, только имя отличается.

Итак, я создал этот вспомогательный класс:

public  class HelperClass
    {

        protected  bool _on;

        public void Drive(string name)
        {

            if (_on)
            {
                Console.WriteLine($"Drive {name}");
            }
            else
            {
                Console.WriteLine($"Have to start {name} first");
            }

        }
    }

Но как теперь использовать HelperClass? так что вы можете просто сказать, в де производном (например, Porsche) классе _on = true, и затем вы получите сообщение: Drive Porsche

и, если _on = false, вы увидите сообщение: Сначала запустите Porsche.

Спасибо

oke,

Я добавил это:

 public class Person
    {
        private Car _car;       
        public Person(Car car)
        {
            this._car = car;
        }
        public void Drive() 
        {          

            this._car.Drive();
        }
    }
 static void Main(string[] args)
        {

            Ford ford = new Ford();
            Person person = new Person(ford);
            person.Drive();
            Console.ReadKey();
        }

Но как это сделать, например, Porsche имеет сообщение: сначала нужно запустить Porsche, и, например, Ford, должен получить сообщение: Drive Ford. Потому что теперь

 protected bool _on { get; set; }

находится в базовом классе

Ответы [ 4 ]

3 голосов
/ 11 апреля 2020

Введите защищенное свойство Name и переместите реализацию Drive() в базовый класс. Похоже, у вас логика c для Drive() перевернута. Разве он не должен позволять вам водить машину, когда _on истинно?

Проверьте этот пример:

public abstract class Car
{
    protected bool _on { get; set; }

    protected virtual string CarName { get; }

    // For demonstration
    public void StartCar() => _on = true;
    public void StopCar() => _on = false;

    public void Drive()
    {
        if (_on)
        {
            Console.WriteLine($"Drive {CarName}");
        }
        else
        {
            Console.WriteLine($"Have to start {CarName} first");
        }
    }
}

public class Renault : Car
{
    protected override string CarName { get => "Renault"; }
}

public class Porsche : Car
{
    protected override string CarName { get => "Porsche "; }
}

Использование:

var renault = new Renault();
renault.Drive();    // Car not started --> _on = false.

var porsche = new Porsche();
porsche.StartCar();
porsche.Drive();   // Car started --> _on = true.

Выход:

Have to start Renault first
Drive Porsche
2 голосов
/ 11 апреля 2020

Вам не нужен вспомогательный класс, и у вас все еще не будет дублированного кода, если вы извлечете общие вещи и переопределите то, что отличается - в вашем случае только тип автомобиля. На самом деле вам даже не нужно несколько классов, так как название машины - это просто название класса. Так что этого достаточно:

public abstract class Car
{      
    private bool _on { get; set; }
    public string Model { get; }

    public Car(string model) { this.Model = model; }

    public void Drive()
    {            
        if (_on)
        {
            Console.WriteLine($"Drive { Model }");
        }
        else
        {
            Console.WriteLine($"Have to start { Model } first");
        }
    }      
}

Тогда вы можете создать Porsche, например:

var p = new Car("Porsche");
p.Drive();
1 голос
/ 11 апреля 2020

Примерно так:

public abstract class Car
{
    protected static bool _on { get; set; }
    public virtual void Drive()
    {
        if (_on)
        {
            Console.WriteLine($"Drive {this.GetType().Name}");
        }
        else
        {
            Console.WriteLine($"Have to start {this.GetType().Name} first");
        }        
    }
}

public class Porsche : Car
{

}

public class Renault : Car
{

}

Код клиента:

var porsche = new Porsche();
porsche.Drive();

var renault = new Renault();
renault.Drive();
1 голос
/ 11 апреля 2020

У вас в основном один и тот же код в обоих производных классах. Предполагая, что это будет одинаково во всех производных классах, вы можете переместить это в базовый класс и затем отобразить имя класса.

public abstract class Car
{
   protected static bool _on { get; set; }  
   public void Drive()
   {
       if (!_on)
       {
           Console.WriteLine($"Drive {this.GetType().Name}");
       }
       else
       {
           Console.WriteLine($"Have to start {this.GetType().Name} first");
       }
   }
}

Кстати: вы уверены, что! _на разрешить вам водить машину? Кажется, что логика c здесь неправильная. Кроме того, что касается комментариев, я не уверен, что _on должен быть stati c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...