Witam
Umiem dość dobrze programować w języku C (miałem 2 semestry C na studiach). W przyszłym semestrze będę się uczyć C++. W związku z tym postanowiłem nauczyć się innego języka obiektowego. Wybrałem C#, uczę się z książki Liberty'ego. Chcę napisać trochę prostych programów, aby w praktyce zrozumieć na czym polega programowanie obiektowe i w czym jest lepsze od programowania proceduralnego. Proszę o podanie kilku programów do napisania, abym mógł przećwiczyć podstawowe aspekty programowania obiektowego.
Dzięki
W przyszłym semestrze będę się uczyć C++. W związku z tym postanowiłem nauczyć się innego języka obiektowego. Wybrałem C#, uczę się z książki Liberty'ego.
Znając C# będziesz się strasznie męczył z absurdami C++ i zastanawiał czemu w C++ tego nie zrobili po ludzku
. Większość studentów nie ma tego problemu bo zaczynają od C++ i myślą że tak musi być
.
Ok, to wymyślamy jakieś ćwiczenia:
Średniotrudne zadanie - Inspirowane raytracingiem.
IMO ciekawe, chociaż raczej nie coś czym można się pochwalić znajomym. Bardzo dobrze pokazuje zalety obiektowości i przewagę nad proceduralnym kodem.
Zaczynamy od takiego kodu (tworzysz nowy projekt i wklejasz):
static class Program
{
[STAThread]
static void Main()
{
const int size = 400;
using (Form form = new Form())
{
PictureBox surface = new PictureBox();
surface.Dock = DockStyle.Fill;
surface.Image = new Bitmap(size, size);
RenderImage(surface);
form.Size = new Size(size, size);
form.MaximumSize = form.Size;
form.Controls.Add(surface);
Application.Run(form);
}
}
static void RenderImage(PictureBox surface)
{
using (Graphics g = Graphics.FromImage(surface.Image))
{
Size size = surface.Image.Size;
for (int x = 0; x < size.Width; x++)
for (int y = 0; y < size.Height; y++)
{
g.SetPixel(x, y, Color.Green);
}
}
}
static void SetPixel(this Graphics g, int x, int y, Color color)
{
g.DrawRectangle(new Pen(color), x, y, 1, 1);
}
}
Jeśli chcesz możesz uruchomić, pojawia się puste okno z zielonym tłem.
Zadania do wykonania:
Proste:
- Stworzyć interfejs IShape posiadający metodę bool HasPoint(int x, int y) (sprawdzającą czy punkt jest wewnątrz figury)
- Stworzyć klasę Circle z konstruktorem Circle(int centerX, int centerY, int radius) implementującą ten interfejs
- Zdefiniować zmienną typu circle w miejscu (1).
- Sprawić żeby RenderImage przyjmowało obiekt klasy circle (miejsce 2), przekazać jej stworzony obiekt.
- Wykonać test na przekazanym kole tak żeby rysować na zielono tylko tam gdzie HasPoint dla circle zwraca true
- Stworzyć klasę Rectangle z konstruktorem Rectangle(int centerX, int centerY, int sizeX, int sizeY) implementującą ten interfejs
- Zmienić circle w RenderImage na rectangle.
- Sprawić żeby RenderImage przyjmowało (i testowało) nie pojedyńczy prostokąt tylko listę prostokątów (List<Rectangle>).
- Sprawić żeby RenderImage przyjmowało listę figur.
- Stworzyć klasę AndShape mającą dwa pola typu IShape której HasPoint zwraca true wtedy i tylko wtedy gdy HasPoint obydwóch pól zwracają true
- Stworzyć klasę XorShape mającą dwa pola typu IShape której HasPoint zwraca true wtedy i tylko wtedy gdy dokładnie jedno HasPoint obydwóch pól zwracaa true
- Stworzyć klasę MinusShape mającą dwa pola typu IShape której HasPoint zwraca true wtedy i tylko wtedy gdy HasPoint pierwszej figury zwraca true a drugiej false
- Stworzyć klasę CombinedShape która umożliwia wykonywanie funkcjonalności poprzednich trzech (i wszystkich innych funkcji logicznych - do tego punktu najlepiej wykorzystać wyrażenie lambda) :>. Wywalić poprzednie trzy klasy z kodu. Zapamiętać że powtarzanie kodu to zło.
- Stworzyć klasę Transformed shape która przyjmuje inną IShape w konstruktorze i
przesuwa
ją (nie znając typu posiadanej figury!) na ekranie. - Stworzyć klasę Rotated shape która przyjmuje inną IShape w konstruktorze i
obraca
ją (nie znając typu posiadanej figury!) na ekranie. - Stworzyć klasę Scaled shape która przyjmuje inną IShape w konstruktorze i
skaluje
ją (nie znając typu posiadanej figury!) na ekranie. - Ewentualnie, klasę Sheared shape
- Jeśli lubisz matematykę - klasę Transformed shape zastępującej powyższe 4 (do napisania za pomocą macierzy - czyli musiałbyś wcześniej stworzyć klasę Matrix przekształcającą punkty)
- Na sam koniec - klasę Triangle/Ellipse/Donut/Cokolwiek implementującą interfejs IShape. Wykonać z nią parę testów. Chwila refleksji jakich zmian wymagałoby to gdyby kod i wszystkie funkcje testujące były napisane proceduralnie.
Jeśli to zrobisz to zgłoś się, wymyślę dalsze punkty albo nowe zadanie :>
Napisz bota indeksującego forum 4programmers.net, który będzie wskazywał podobne wątki...