Используйте классы для определения объектов: Используйте классы для определения свойств и методов ваших объектов. Класс - это чертеж объекта, определяющий его поведение.
Все примеры будут приведены на языке C#
public class Car
{
// Fields
private string make;
private string model;
private int year;
// Constructor
public Car(string make, string model, int year)
{
this.make = make;
this.model = model;
this.year = year;
}
// Properties
public string Make
{
get { return make; }
set { make = value; }
}
public string Model
{
get { return model; }
set { model = value; }
}
public int Year
{
get { return year; }
set { year = value; }
}
// Methods
public void Start()
{
Console.WriteLine("The car has started.");
}
public void Stop()
{
Console.WriteLine("The car has stopped.");
}
}
В этом примере мы определяем класс Car с тремя полями: марка, модель и год выпуска. Мы также определяем конструктор для установки этих полей при создании нового объекта Car.
Затем мы определим свойства для каждого поля, которые позволят нам получить или установить значение полей. Наконец, мы определяем два метода, Start и Stop, которые имитируют запуск и остановку автомобиля.
С помощью этого определения класса мы можем создавать новые объекты Car и использовать методы и свойства для взаимодействия с ними:
Car myCar = new Car("Toyota", "Camry", 2021);
Console.WriteLine($"My car is a {myCar.Make} {myCar.Model} from {myCar.Year}.");
myCar.Start();
myCar.Stop();
Инкапсулируйте свой код: Инкапсуляция - это практика сокрытия деталей реализации от внешнего мира. Обычно это достигается путем создания приватных полей и предоставления публичных свойств или методов для доступа к ним.
public class BankAccount
{
// Fields
private decimal balance;
// Constructor
public BankAccount(decimal initialBalance)
{
balance = initialBalance;
}
// Properties
public decimal Balance
{
get { return balance; }
private set { balance = value; }
}
// Methods
public void Deposit(decimal amount)
{
if (amount > 0)
{
Balance += amount;
}
}
public void Withdraw(decimal amount)
{
if (amount > 0 && amount <= Balance)
{
Balance -= amount;
}
}
}
В этом примере мы определяем класс BankAccount с единственным полем balance, которое делается приватным для инкапсуляции деталей реализации от внешнего доступа. Мы также определяем конструктор, который устанавливает начальный баланс при создании нового объекта BankAccount.
Затем мы определяем публичное свойство Balance, которое позволяет внешнему коду читать значение баланса, но не позволяет внешнему коду изменять его. Это достигается путем предоставления приватного аксессора set, который может быть вызван только из класса.
Мы также определяем два метода, Deposit и Withdraw, которые позволяют внешнему коду взаимодействовать с объектом BankAccount путем внесения или снятия средств. Однако мы гарантируем, что эти методы могут изменять баланс только при определенных условиях, что помогает обеспечить целостность счета.
С помощью этого определения класса мы можем создавать новые объекты BankAccount и взаимодействовать с ними, используя публичные методы и свойства:
BankAccount myAccount = new BankAccount(1000);
Console.WriteLine($"My account balance is {myAccount.Balance}.");
myAccount.Deposit(500);
Console.WriteLine($"My account balance is {myAccount.Balance}.");
myAccount.Withdraw(200);
Console.WriteLine($"My account balance is {myAccount.Balance}.");
Наследуйте от базовых классов: Наследование - это способ определения нового класса на основе существующего. Это может помочь вам повторно использовать код и избежать дублирования функциональности.
public class Animal
{
// Fields
protected string name;
protected int age;
// Constructor
public Animal(string name, int age)
{
this.name = name;
this.age = age;
}
// Methods
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound.");
}
}
public class Dog : Animal
{
// Constructor
public Dog(string name, int age) : base(name, age)
{
}
// Methods
public override void MakeSound()
{
Console.WriteLine("The dog barks.");
}
public void WagTail()
{
Console.WriteLine("The dog wags its tail.");
}
}
В этом примере мы определяем базовый класс Animal с двумя полями, имя и возраст, и конструктор, который устанавливает эти поля при создании нового объекта Animal. Мы также определяем виртуальный метод MakeSound, который может быть переопределен производными классами.
Затем мы определяем производный класс Dog, который наследуется от Animal. Класс Dog имеет свой конструктор, который вызывает конструктор базового класса для установки полей имени и возраста. Класс Dog также переопределяет метод MakeSound, чтобы задать уникальное поведение для собак.
Кроме того, класс Dog имеет свой собственный метод WagTail, которого нет в базовом классе Animal.
С помощью этой иерархии классов мы можем создавать новые объекты Animal и Dog и вызывать их соответствующие методы:
Animal myAnimal = new Animal("Generic Animal", 5);
myAnimal.MakeSound();
Dog myDog = new Dog("Fido", 3);
myDog.MakeSound();
myDog.WagTail();
Используйте интерфейсы: Интерфейс - это контракт, определяющий набор методов и свойств, которые должен реализовать класс. Это обеспечивает полиморфизм и позволяет сделать ваш код более легко тестируемым и расширяемым.
public interface IShape
{
double GetArea();
double GetPerimeter();
}
public class Rectangle : IShape
{
// Fields
private double length;
private double width;
// Constructor
public Rectangle(double length, double width)
{
this.length = length;
this.width = width;
}
// Methods
public double GetArea()
{
return length * width;
}
public double GetPerimeter()
{
return 2 * (length + width);
}
}
public class Circle : IShape
{
// Fields
private double radius;
// Constructor
public Circle(double radius)
{
this.radius = radius;
}
// Methods
public double GetArea()
{
return Math.PI * radius * radius;
}
public double GetPerimeter()
{
return 2 * Math.PI * radius;
}
}
В этом примере мы определяем интерфейс IShape, который определяет два метода, GetArea и GetPerimeter. Затем мы определяем два класса, Rectangle и Circle, которые реализуют интерфейс IShape.
Класс Rectangle имеет два поля, длина и ширина, и конструктор, который устанавливает эти поля при создании нового объекта Rectangle. Класс Rectangle реализует методы GetArea и GetPerimeter для вычисления площади и периметра прямоугольника.
Класс Circle имеет единственное поле, радиус, и конструктор, который устанавливает это поле при создании нового объекта Circle. Класс Circle также реализует методы GetArea и GetPerimeter для вычисления площади и периметра круга.
С помощью этого интерфейса и иерархии классов мы можем создавать новые объекты Rectangle и Circle и вызывать их соответствующие методы GetArea и GetPerimeter:
Rectangle myRectangle = new Rectangle(5, 3);
double rectangleArea = myRectangle.GetArea();
double rectanglePerimeter = myRectangle.GetPerimeter();
Circle myCircle = new Circle(2);
double circleArea = myCircle.GetArea();
double circleCircumference = myCircle.GetPerimeter();
Используйте модификаторы доступа: Модификаторы доступа позволяют вам контролировать видимость вашего кода. Используйте модификаторы private, protected и public, чтобы контролировать, откуда можно получить доступ к вашему коду.
public class MyClass
{
public int publicField;
private int privateField;
protected int protectedField;
internal int internalField;
public MyClass(int publicValue, int privateValue, int protectedValue, int internalValue)
{
this.publicField = publicValue;
this.privateField = privateValue;
this.protectedField = protectedValue;
this.internalField = internalValue;
}
public void PublicMethod()
{
Console.WriteLine("This is a public method.");
}
private void PrivateMethod()
{
Console.WriteLine("This is a private method.");
}
protected void ProtectedMethod()
{
Console.WriteLine("This is a protected method.");
}
internal void InternalMethod()
{
Console.WriteLine("This is an internal method.");
}
}
В этом примере мы определяем класс MyClass с четырьмя полями и четырьмя методами, каждый из которых имеет свой модификатор доступа.
Поле publicField имеет модификатор доступа public, что означает, что к нему можно получить доступ из любого внешнего кода. Поле privateField имеет модификатор доступа private, что означает, что доступ к нему возможен только из класса MyClass. Поле protectedField имеет модификатор доступа protected, что означает, что к нему можно обращаться из класса MyClass и любых производных классов. Поле internalField имеет модификатор внутреннего доступа, что означает, что к нему можно обращаться из той же сборки (т.е. из того же файла .exe или .dll).
Метод PublicMethod имеет модификатор доступа public, что означает, что к нему можно обращаться из любого внешнего кода. Метод PrivateMethod имеет модификатор доступа private, что означает, что доступ к нему возможен только из класса MyClass. Метод ProtectedMethod имеет модификатор доступа protected, что означает, что к нему можно обращаться из класса MyClass и любых производных классов. Метод InternalMethod имеет модификатор внутреннего доступа, что означает, что к нему можно обращаться из той же сборки.
С помощью этого определения класса мы можем создавать новые объекты MyClass и получать доступ к их полям и методам:
MyClass myObject = new MyClass(1, 2, 3, 4);
// Access public field
int publicValue = myObject.publicField;
// Access private field (will not compile)
// int privateValue = myObject.privateField;
// Access protected field (will not compile)
// int protectedValue = myObject.protectedField;
// Access internal field
int internalValue = myObject.internalField;
// Call public method
myObject.PublicMethod();
// Call private method (will not compile)
// myObject.PrivateMethod();
// Call protected method (will not compile)
// myObject.ProtectedMethod();
// Call internal method
myObject.InternalMethod();
Используйте абстракцию: Абстракция - это практика упрощения сложного кода путем сокрытия ненужных деталей. Это часто делается путем определения абстрактных классов или интерфейсов.
public abstract class Shape
{
public abstract double GetArea();
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double GetArea()
{
return Math.PI * Radius * Radius;
}
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override double GetArea()
{
return Width * Height;
}
}
В этом примере мы определяем абстрактный класс Shape с абстрактным методом GetArea(). Этот метод не имеет тела и должен быть реализован в любых конкретных классах, производных от класса Shape. Класс Shape нельзя инстанцировать напрямую, поскольку он является абстрактным.
Мы также определяем два конкретных класса, которые являются производными от класса Shape: Circle и Rectangle. Оба класса реализуют метод GetArea(), но каждый использует свою формулу для вычисления площади.
С помощью этого определения класса мы можем создавать новые объекты Circle и Rectangle и вызывать их методы GetArea(), не зная и не заботясь о деталях реализации:
Circle circle = new Circle();
circle.Radius = 5;
double circleArea = circle.GetArea();
Rectangle rectangle = new Rectangle();
rectangle.Width = 10;
rectangle.Height = 5;
double rectangleArea = rectangle.GetArea();
Используйте полиморфизм: Полиморфизм - это способность объекта принимать различные формы. Это часто достигается с помощью наследования и интерфейсов и позволяет сделать код более гибким и адаптируемым.
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("The dog barks");
}
}
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("The cat meows");
}
}
В этом примере мы определяем базовый класс Animal с виртуальным методом MakeSound(), который просто записывает сообщение в консоль. Затем мы определяем два производных класса, Dog и Cat, которые переопределяют метод MakeSound(), чтобы реализовать свой собственный уникальный звук.
Теперь мы можем создавать экземпляры классов Dog и Cat и вызывать их методы MakeSound(). Когда мы вызываем метод MakeSound() на объекте Dog или Cat, он вызовет переопределенный метод соответствующего класса и запишет соответствующий звук на консоль:
Animal myAnimal = new Animal();
myAnimal.MakeSound(); // Outputs "The animal makes a sound"
Animal myDog = new Dog();
myDog.MakeSound(); // Outputs "The dog barks"
Animal myCat = new Cat();
myCat.MakeSound(); // Outputs "The cat meows"
Следуя этим советам, вы сможете писать чистый, удобный и расширяемый код в объектно-ориентированном стиле на C#.