Zrozumienie mechanizmu inicjalizacji obiektów za pomocą różnych typów konstruktorów oraz nauka przeciążania metod i konstruktorów. Student pozna sposoby łańcuchowania wywołań konstruktorów przy użyciu słowa kluczowego this oraz dowie się, jak działa destruktor klasy.
W komisie "Auto-Premium" proces wprowadzania danych staje się uciążliwy. Pracownicy narzekają, że za każdym razem po utworzeniu obiektu muszą ręcznie wpisywać każde pole z osobna. Chciałbyś, aby system pozwalał na tworzenie pojazdu od razu z podstawowymi danymi (np. tylko marką i modelem), zachowując jednocześnie możliwość utworzenia zupełnie pustego obiektu lub pełnego opisu.
Postanawiasz wyposażyć klasę "Samochod" w zestaw specjalnych metod – konstruktorów. Dzięki ich przeciążeniu, system zyska na elastyczności. Dodatkowo, wprowadzasz funkcję obniżania ceny pojazdu, która może działać na dwa sposoby: poprzez odjęcie konkretnej kwoty lub procentowe obniżenie wartości. Aby zachować przejrzystość kodu, wykorzystujesz łańcuchowanie konstruktorów, co pozwala uniknąć powielania logiki inicjalizacji. Na koniec dodajesz destruktor, który będzie informował system o tym, że dany obiekt kończy swoją drogę w pamięci operacyjnej i jest gotowy do usunięcia przez mechanizm sprzątający środowiska .NET.
using System;
namespace LaboratoriumOOP
{
public class Samochod
{
private string _marka;
private string _model;
private int _rokProdukcji;
private double _cena;
// 1. Konstruktor bezargumentowy (jawny)
// Łańcuchowanie: wywołuje pełny konstruktor z domyślnymi wartościami
public Samochod() : this("Nieznana", "Nieznany", 2000, 0.0)
{
Console.WriteLine("[LOG] Utworzono pusty obiekt (konstruktor bezargumentowy).");
}
// 2. Konstruktor z 2 parametrami
public Samochod(string marka, string model) : this(marka, model, DateTime.Now.Year, 10000.0)
{
Console.WriteLine($"[LOG] Utworzono obiekt {marka} {model} (konstruktor 2-arg).");
}
// 3. Pełny konstruktor (główny)
public Samochod(string marka, string model, int rokProdukcji, double cena)
{
// Słowo 'this' wskazuje na pole klasy, unikając konfliktu z parametrem
this._marka = marka;
this._model = model;
this._rokProdukcji = rokProdukcji;
this._cena = cena;
Console.WriteLine($"[LOG] Pełna inicjalizacja: {marka} {model}.");
}
// DESTRUKTOR: Wywoływany przez Garbage Collector przed usunięciem z pamięci.
~Samochod()
{
// UWAGA: Destruktorów unika się, jeśli nie zwalniamy zasobów niezarządzanych.
// Tutaj służy jedynie do celów edukacyjnych.
Console.WriteLine($"[GC] Obiekt {_marka} {_model} został usunięty z pamięci.");
}
// PRZECIĄŻANIE METOD (Overloading)
// Ta sama nazwa, ale inna lista parametrów.
public void ObnizCene(double kwota)
{
_cena -= kwota;
Console.WriteLine($"Cena obniżona o {kwota} PLN. Nowa cena: {_cena} PLN.");
}
public void ObnizCene(int procent)
{
double obnizka = _cena * (procent / 100.0);
_cena -= obnizka;
Console.WriteLine($"Cena obniżona o {procent}%. Nowa cena: {_cena} PLN.");
}
public void Wyswietl()
{
Console.WriteLine($"Pojazd: {_marka} {_model} ({_rokProdukcji}), Cena: {_cena} PLN");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("--- ZADANIE 03: Konstruktory i przeciążanie ---\n");
// Tworzenie obiektów różnymi sposobami
Samochod s1 = new Samochod();
Samochod s2 = new Samochod("Ford", "Focus");
Samochod s3 = new Samochod("BMW", "X5", 2021, 250000.0);
Console.WriteLine("\nStan pojazdów:");
s1.Wyswietl();
s2.Wyswietl();
s3.Wyswietl();
Console.WriteLine("\nDemonstracja przeciążania metod:");
s2.ObnizCene(1500.50); // Metoda z double
s3.ObnizCene(10); // Metoda z int (procenty)
Console.WriteLine("\nKoniec programu. Obiekty zostaną usunięte...");
// Sugestia dla Garbage Collectora, aby posprzątał (tylko do demonstracji destruktora)
s1 = null; s2 = null; s3 = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("\nNaciśnij klawisz...");
Console.ReadKey();
}
}
}