diff --git a/README.md b/README.md index 90a896cbd..904d640fa 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,117 @@ -# Object Oriented Programming - Coders School +# Programowanie obiektowe + ## [Moduł 1](module1/) -### [Wprowadzenie do programowania obiektowego](module1/presentation_oop_intro.md) +### [Wprowadzenie](module1/00_intro.pl.md) -### [Modyfikatory dostępu](module1/presentation_access_modifiers.md) +### [Modyfikatory dostępu](module1/01_access_modifiers.pl.md) -### [Konstruktory i destruktory](module1/presentation_ctor_dtor.md) +### [Konstruktory i destruktory](module1/02_ctor_dtor.pl.md) -### [Hermetyzacja](module1/presentation_hermetization.md) +### [Hermetyzacja](module1/03_hermetization.pl.md) -### [Zadania](module1/presentation_tasks.md) +### [Zadania](module1/04_tasks.pl.md) -### [Projekt grupowy](module1/presentation_homework.md) +### [Zadanie domowe](module1/05_homework.pl.md) ## [Moduł 2](module2/) -### [Dziedziczenie](module2/presentation_inheritance.md) +### [Dziedziczenie](module2/00_inheritance.pl.md) -### [Metody wirtualne, interfejsy, klasy abstrakcyjne](module2/presentation_virtual.md) +### [Metody wirtualne, interfejsy, klasy abstrakcyjne](module2/01_virtual.pl.md) -### [Polimorfizm](module2/presentation_polymorphism.md) +### [Polimorfizm](module2/02_polymorphism.pl.md) -### [Zmienne i funkcje statyczne](module2/presentation_static.md) +### [Zmienne i funkcje statyczne](module2/03_static.pl.md) -### [Projekt grupowy](module2/presentation_homework.md) +### [Zadanie domowe](module2/04_homework.pl.md) + +### [Przykładowe rozwiązania](module2/05_solutions.pl.md) ## [Moduł 3](module3/) -### [Przykładowe rozwiązania](module3/presentation_solutions.md) +### [Przykładowe rozwiązania](module3/00_solutions.pl.md) -### [Polimorfizm](module3/presentation_polymorphism.md) +### [Polimorfizm](module3/01_polymorphism.pl.md) -### [Zmienne i funkcje statyczne](module3/presentation_static.md) +### [Zmienne i funkcje statyczne](module3/02_static.pl.md) -### [Projekt grupowy](module3/presentation_homework.md) +### [Zadanie domowe](module3/03_homework.pl.md) ## [Moduł 4](module4/) -### [Cztery filary obiektowości](module4/pillars.md) +### [Cztery filary obiektowości](module4/00_pillars.pl.md) + +### [Abstrakcja](module4/01_abstraction.pl.md) + +### [Enkapsulacja](module4/02_encapsulation.pl.md) + +### [Dziedziczenie](module4/03_inheritance.pl.md) + +### [Polimorfizm](module4/04_polymorphism.pl.md) + +### [Zadanie](module4/05_exercise_cars.pl.md) + +### [Post-work](module4/06_post_work.pl.md) + +___ + +# Object Oriented Programming + +## [Module 1](module1/) + +### [Introduction](module1/00_intro.en.md) + +### [Access modifiers](module1/01_access_modifiers.en.md) + +### [Constructors and destructors](module1/02_ctor_dtor.en.md) + +### [Hermetization](module1/03_hermetization.en.md) + +### [Exercises](module1/04_tasks.en.md) + +### [Homework](module1/05_homework.en.md) + +## [Module 2](module2/) + +### [Inheritance](module2/00_inheritance.en.md) + +### [Virtual methods, interfaces, abstract classes](module2/01_virtual.en.md) + +### [Polymorphism](module2/02_polymorphism.en.md) + +### [Static variables and functions](module2/03_static.en.md) + +### [Homework](module2/04_homework.en.md) + +### [Examples of solutions](module2/05_solutions.en.md) + +## [Module 3](module3/) + +### [Examples of solutions](module3/00_solutions.en.md) + +### [Polymorphism](module3/01_polymorphism.en.md) + +### [Static variables and functions](module3/02_static.en.md) + +### [Homework](module3/03_homework.en.md) + +## [Module 4](module4/) + +### [The four pillars of objectivity](module4/00_pillars.en.md) -### [Abstrakcja](module4/abstraction.md) +### [Abstraction](module4/01_abstraction.en.md) -### [Enkapsulacja](module4/encapsulation.md) +### [Encapsulation](module4/02_encapsulation.en.md) -### [Dziedziczenie](module4/inheritance.md) +### [Inheritance](module4/03_inheritance.en.md) -### [Polimorfizm](module4/polymorphism.md) +### [Polymorphism](module4/04_polymorphism.en.md) -### [Zadanie](module4/exercise_cars.md) +### [Exercise](module4/05_exercise_cars.en.md) -### [Post-work](module4/post_work.md) +### [Post-work](module4/06_post_work.en.md) diff --git a/module1/00_intro.en.md b/module1/00_intro.en.md new file mode 100644 index 000000000..34812e2c9 --- /dev/null +++ b/module1/00_intro.en.md @@ -0,0 +1,122 @@ + + +# Object oriented programming + + + Coders School + + +___ + +## SHM (pol. Symulator Handlu Morskiego) - Sea Trade Simulator + +Statek + +___ + + +## SHM - UML diagram + + + Diagram klas - SHM + + +___ + +## Introduction to object oriented programming + +___ + +### What is an Object? + +An object in C++ is no different from an actual object in real life. An object is a "specific" object. We can have many identical objects. Some of them can be distinguished by names. In C++ we can have objects such as: + +* HP computer, Lenovo computer, MacBook computer +* HP printer, Epson printer +* Stabilo Schwan 306 HB pencil = 2 1/2 +* Casio calculator +* ... + +The object exists in computer memory while the program is running. We can have many objects of the same type. + + +* Type: Dog +* Objects of type Dog: Max, Milo, Coco, ... + +___ + +### What is a class? + +A class is a type. + + +A class in C++ is slightly different from an actual class 🙂 In C++ (or object-oriented programming in general) a class defines the characteristics of an object: + + +* what properties will this object have (fields) +* what methods of operation will it have (methods, functions) + +___ + +### Questions + +* what properties could a computer object have? +* what methods could the computer have? + +```cpp +class Computer { + // fields + Processor processor_; + Drive drive_; + Motherboard motherboard_; + GraphicsCard graphics_card_; + Memory memory_; + + // methods + void run(); + void restart(); + void shutdown(); +}; +``` + + +___ + +## Composition, aggregation + +Nothing prevents one object from being composed of other objects. In this way, we make the structure of our code more understandable. + +Containing one object within another is called composition or aggregation. These are not synonyms, they are two slightly different types of object containment, but that doesn't matter at the moment. For example with a computer: + + +```cpp +class Computer { + Processor processor_; + Drive drive_; + Motherboard motherboard_; + GraphicsCard graphics_card_; + Memory memory_; + // ... +}; +``` + + +A computer consists (is composed of) of a processor, drive, motherboard, graphics card, memory. + + +___ + + +## Class diagram - composition, aggregation + +Kompozycja i agregacja + +* Composition: A car contains exactly 1 Carburetor. The carburetor is part of exactly one car. Without a car, the carburetor does nothing, so it cannot function without it. +* Aggregation: Pond can contain any number (0 .. *) of Ducks. The duck may be in only one pond at a time or in none (0..1). The duck can live outside the pond. + +[Class diagram - wikipedia](https://en.wikipedia.org/wiki/Class_diagram) + + +___ + +## Q&A diff --git a/module1/presentation_oop_intro.md b/module1/00_intro.pl.md similarity index 96% rename from module1/presentation_oop_intro.md rename to module1/00_intro.pl.md index ce6672d85..52f02ae8a 100644 --- a/module1/presentation_oop_intro.md +++ b/module1/00_intro.pl.md @@ -50,7 +50,7 @@ ___ Klasa to typ. -Klasa w C++ nieco różni się od rzeczywistej klasy :) W C++ (czy też programowaniu obiektowym ogólnie) klasa określa cechy obiektu: +Klasa w C++ nieco różni się od rzeczywistej klasy 🙂 W C++ (czy też programowaniu obiektowym ogólnie) klasa określa cechy obiektu: * jakie właściwości będzie miał ten obiekt (pola) diff --git a/module1/01_access_modifiers.en.md b/module1/01_access_modifiers.en.md new file mode 100644 index 000000000..1a310ebde --- /dev/null +++ b/module1/01_access_modifiers.en.md @@ -0,0 +1,62 @@ + + +# Object oriented programming + +## Access modifiers + + + Coders School + + +___ + +## `class` vs `struct` + +To represent types outside classes (`class`) we still have structures (`struct`). + + +The main difference is that all structure elements - its methods and variables - are public by default. By contrast, in the class they are private by default. + + +Word `private` means that we only have access to these fields inside the class. We cannot appeal to them outside of this class. Word `public` means that we have external access to the data. + + +___ + +## Access modifiers + +### `private` vs `public` + +```cpp +class Computer { +private: + void restart(); +}; + +Computer computer; +computer.restart(); // Forbidden, restart is a private member +``` + + +```cpp +class Computer { +public: + void restart(); +}; + +Computer computer; +computer.restart(); // Ok +``` + + +___ + +### Access modifier `protected` + +There is one more access modifier in C++ - `protected`. + +We will tell about it when we explain what inheritance is. + +___ + +## Q&A diff --git a/module1/presentation_access_modifiers.md b/module1/01_access_modifiers.pl.md similarity index 97% rename from module1/presentation_access_modifiers.md rename to module1/01_access_modifiers.pl.md index 372a30740..d1a8f36e3 100644 --- a/module1/presentation_access_modifiers.md +++ b/module1/01_access_modifiers.pl.md @@ -51,7 +51,7 @@ computer.restart(); // Ok ___ -## Modyfikator dostępu `protected` +### Modyfikator dostępu `protected` Istnieje jeszcze jeden modyfikator dostępu w C++ - `protected`. diff --git a/module1/02_ctor_dtor.en.md b/module1/02_ctor_dtor.en.md new file mode 100644 index 000000000..61f0debc4 --- /dev/null +++ b/module1/02_ctor_dtor.en.md @@ -0,0 +1,146 @@ + + +# Object oriented programming + +## Constructors and destructors + + + Coders School + + +___ + +## Constructor + +The class constructor is a recipe that determines how our class should look at the time of creation. + + +This is a special function with the same name as the class. + + +We can provide the constructor with all the information we need, e.g. the size of the array, the date of purchase, etc. + + +```cpp +class Ship { +public: + Ship(const std::string& name, size_t capacity); // constructor, c-tor + +private: + std::string name_; + const size_t capacity_; +}; +``` + + +___ + +## Constructors + +A class can have multiple constructors. They must differ in the parameter list because they are function overloads. + + +A class may have, among others argumentless (default) constructor e.g. `Ship()` which is automatically generated if it has no other constructor defined. + + +```cpp +class Ship { + // default c-tor Ship() is generated automatically, no need to write it + std::string name_; + const size_t capacity_; +}; +``` + + +___ + +## Constructor initialization list + +We can use the initialization list to initialize the data in the constructor. + + +The initialization list is written after the constructor signature after the colon. + + +```cpp +class Processor { +public: + Processor(unsigned clock, size_t cores) + : clock_(clock), cores_(cores) // init-list + {} + + // the effect of above constructor is the same as below + // Processor(unsigned clock, size_t cores) { + // clock_ = clock; + // cores_ = cores; + // } + +private: + unsigned clock_; + size_t cores_; +} +``` + + +___ + +## Constructor delegation + +An element of the initialization list can even be another constructor of our class. + + +```cpp +class Ship { +public: + Ship(const std::string& name, size_t capacity, size_t crew): + name_(name), capacity_(capacity), crew_(crew) + {} + + Ship(const std::string& name, size_t capacity): + Ship(name, capacity, 0) + {} + +private: + std::string name_; + const size_t capacity_; + size_t crew_; +}; +``` + + +___ + + +## Destructor + +Destructor is a special function to clean our class. + + +Must be named the same as the class, but preceded by a tilde character `~`. + + +We can use it if we want to trigger specific actions while destroying the object, e.g. registering this fact in the log, etc. + + +```cpp +class Ship { +public: + Ship(const std::string& name, size_t capacity, size_t crew): + name_(name), capacity_(capacity), crew_(crew) + {} + + ~Ship() { // d-tor, destruktor + std::cout << "Ship destroyed\n"; + } + +private: + std::string name_; + const size_t capacity_; + size_t crew_; +}; +``` + + +___ + +## Q&A diff --git a/module1/presentation_ctor_dtor.md b/module1/02_ctor_dtor.pl.md similarity index 100% rename from module1/presentation_ctor_dtor.md rename to module1/02_ctor_dtor.pl.md diff --git a/module1/03_hermetization.en.md b/module1/03_hermetization.en.md new file mode 100644 index 000000000..263185f6d --- /dev/null +++ b/module1/03_hermetization.en.md @@ -0,0 +1,49 @@ + + +# Object oriented programming + +## Hermetization + + + Coders School + + +___ + +## Hermetization + +In order to protect our object against unwanted modifications, we can make the so-called hermetization or encapsulation. + + +It consists in placing all properties (fields) in the private section and enabling their modification by public functions. + + +___ + +## setters and getters + +The simplest functions that allow modifications are the so-called setters. + + +A setter is a function that assigns a given value to a specific variable. + + +```cpp +void setName(const std::string& name) { name_ = name; } +``` + + +Since the data is private, it is also not possible to read it, so we do it through getters. + + +```cpp +std::string getName() const { return name_ } +``` + + +Of course, we don't always need to allow all variables to be modified, just as not all variables can have getters. The choice is up to the developer. + + +___ + +## Q&A diff --git a/module1/presentation_hermetization.md b/module1/03_hermetization.pl.md similarity index 100% rename from module1/presentation_hermetization.md rename to module1/03_hermetization.pl.md diff --git a/module1/04_tasks.en.md b/module1/04_tasks.en.md new file mode 100644 index 000000000..6226fbbf9 --- /dev/null +++ b/module1/04_tasks.en.md @@ -0,0 +1,66 @@ + + +# Object oriented programming + +## Exercises + + + Coders School + + +___ + +## Exercise 1 + +Write a class `Ship` which will store the ship's data: + +* `id_` +* `name_` +* `speed_` +* `maxCrew_` +* `capacity_` + +The data should be private, and access to it should be through getters. + +___ + +## Exercise 2 + +Add to class `Ship` constructors that will accept the appropriate data. There should be 3 constructors: + +* The first one takes no arguments -> `id_` for such an object should be `-1` +* The second accepting all data +* Third takes `id`, `speed` and `maxCrew` (try to use the second constructor when writing the third one) + +Additionally, add a method `void set_name(const std::string&)`. + +___ + +## Exercise 3 + +Add to class `Ship`: + +* variable `size_t crew_` specifying the current number of the ship's crew +* `Ship& operator+=(const int)` that will add the crew to the ship +* `Ship& operator-=(const int)` that will subtract it. + +___ + +## Exercise 4 + +Create a class `Cargo`. It is supposed to represent 1 type of good on the ship. It will have 3 fields: + +* `name_` - product name +* `amount_` - amount of stock +* `basePrice_` - the base price of the good + +Then write in class `Cargo`: + +* `Cargo& operator+=(const size_t)` that will add the specified quantity of the goods +* `Cargo& operator-=(const size_t)` which will subtract the given quantity of goods + +Also consider how you will store goods on board. + +___ + +## Q&A diff --git a/module1/presentation_tasks.md b/module1/04_tasks.pl.md similarity index 100% rename from module1/presentation_tasks.md rename to module1/04_tasks.pl.md diff --git a/module1/05_homework.en.md b/module1/05_homework.en.md new file mode 100644 index 000000000..2c6627e44 --- /dev/null +++ b/module1/05_homework.en.md @@ -0,0 +1,146 @@ + + +# Object oriented programming + +## Summary + + + Coders School + + +___ + +## What do you remember from today? + +### Write as many keywords as possible in the chat + + +1. class +2. objects +3. fields, properties +4. methods, functions of the class +5. access modifiers - public, private +6. constructors +7. destructors +8. hermetization +9. getters +10. setters + +___ + +### Pre-work + +* Read and watch videos on inheritance and polymorphism + +___ + +## Group project + +Use the code written during the class. You can also use the code in the [solutions](solutions) directory + +Group project. Recommended groups of 5 (4-6 are also ok). + +Make a Fork of this repo and the whole project is going to be in the [shm](../shm) directory + +Collaborate on one fork with a branch or Pull Requests from your own forks. + +___ + +## Organization of work + +To divide tasks and track your status, you can use the [Projects on GitHub](https://github.com/coders-school/object-oriented-programming/projects) tab. You can configure it from the Automated kanban with reviews template. + +### Planning + +Begin with planning where you create cards for each task in the To Do column. It's best to convert them to Issues. Thanks to this, you can assign to tasks and write comments in them. Also write for each task how many days of work you estimate it for. After finishing planning, please send a link to the `#planning` channel to your project board on GitHub. + +### Daily + +Update your tasks as you work. Synchronize at the same time every day and talk about the problems. + +___ + +### Code Review + +Each task delivery must be preceded by a Code Review by another person from the team (or preferably several) to maintain consistency and cooperation. + +### Completion + +This project will be developed even further. We expect that, regardless of the number of completed tasks, you will do a Pull Request before June 28 (in Scrum, the team decides how many tasks they can do for a specific date). + +___ + +### Punctation + +* Each delivered task is worth 5 points +* 20 points for all 8 tasks delivered before 6/28/2020 (Sunday) by 11:59 PM +* no bonus points for delivering only part of tasks before 28/06. +* 6 points for group work for each person in the group. + +___ + +## Task 1 + +In class `Cargo` write the comparison operator (`operator==`), which will check if the goods are the same. + +___ + +## Exercise 2 + +Add getters to the class `Cargo` and an appropriate constructor that will fill all the fields of this class. + +___ + +## Exercise 3 + +Write a class `Island` which will hold the variable `Coordinates position_` and the appropriate getter. + +`Coordinates` class has to determine the coordinates on the map. Write it as well. It should take 2 parameters in the constructor `positionX`, `positionY` and the comparison operator. + + +___ + +## Task 4 + +Write a class `Map` that will have `std::vector` which stores all the islands on the map, and a variable `Island* currentPosition_` determining the current position of the player on the map. + +___ + +## Task 5 + +In class `Map` create an argumentless constructor and create 10 islands in its body that you store in `std::vector`. +To generate random values ​​for the position of the islands on the map use this [example on cppreference](https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution). +Find a way to prevent the positions of the islands from duplicating. + +___ + +## Task 6 + +In class `Map` write function + +`Island* getIsland(const Island::Coordinates& coordinate)` + +It should search `std::vector` and return the island you are looking for. + +___ + +## Task 7 + +Write a class `Player` which will have 3 fields: + +* `std::shared_ptr ship_` (for those willing, try to use `std::unique_ptr<>`) +* `money_` +* `availableSpace_` + +Also add the appropriate getters and constructor. + +Also add 2 functions that should return ship data: + +* `size_t getSpeed() const` +* `Cargo* getCargo(size_t index) const` + +___ + +## Task 8 + +In class `Player` write a private function that will calculate `availableSpace_` based on the current quantity of goods on board. diff --git a/module1/presentation_homework.md b/module1/05_homework.pl.md similarity index 99% rename from module1/presentation_homework.md rename to module1/05_homework.pl.md index 522d7302e..aec0a85ef 100644 --- a/module1/presentation_homework.md +++ b/module1/05_homework.pl.md @@ -19,7 +19,7 @@ ___ 2. obiekty 3. pola, właściwości 4. metody, funkcje klasy -5. modyfikatory dostępu - `public`, `private` +5. modyfikatory dostępu - public, private 6. konstruktory 7. destruktory 8. hermetyzacja diff --git a/module1/index.en.html b/module1/index.en.html new file mode 100644 index 000000000..99ce19bb6 --- /dev/null +++ b/module1/index.en.html @@ -0,0 +1,151 @@ + + + + + + + Object Oriented Programming - Coders School + + + + + + + + + + + + + + + +
+
+
+
+ +

OOP #1

+

Object-Oriented Programming #1

+ + Coders School + +

Mateusz Adamski

+

Łukasz Ziobroń

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +

Coders School

+ Coders School + +
+
+
+ + + + + + diff --git a/module1/index.html b/module1/index.pl.html similarity index 88% rename from module1/index.html rename to module1/index.pl.html index 8fa60eda0..de850eceb 100644 --- a/module1/index.html +++ b/module1/index.pl.html @@ -4,7 +4,7 @@ - Object Oriented Programming - Coders School + Programowanie obiektowe - Coders School @@ -32,7 +32,7 @@

OOP #1

-

Object-Oriented Programming #1

+

Programowanie obiektowe #1

Coders School @@ -63,9 +63,7 @@

Łukasz Ziobroń

## Zadania - Repo GH `coders-school/object-oriented-programming` - - [https://github.com/coders-school/object-oriented-programming/tree/master/module1](https://github.com/coders-school/object-oriented-programming/tree/master/module1) + [Repo GH `coders-school/object-oriented-programming`](https://github.com/coders-school/object-oriented-programming/tree/master/module1)
@@ -95,27 +93,27 @@

Łukasz Ziobroń

You can change the port by using npm start -- --port=8001. --> -
-
-
-
-
-
diff --git a/module2/00_inheritance.en.md b/module2/00_inheritance.en.md new file mode 100644 index 000000000..3191e9191 --- /dev/null +++ b/module2/00_inheritance.en.md @@ -0,0 +1,363 @@ + + +# Object oriented programming + +## Inheritance + + + Coders School + + +___ + +## Introduction to Inheritance + +When implementing classes, we can often notice that some of the class's component features can also be used in other classes. + + +Let's take a closer look at the class `Computer`. If we would like to create classes: `Laptop`, `PC`, `Tablet`, we would have to duplicate some of the methods and class members. + + +___ + +## `class Computer` + +```cpp +class Computer { +public: + void turnOn(); + void powerOff(); + void restart(); + +private: + Processor processor_; + Drive drive_; + Motherboard motherboard_; + GraphicsCard graphics_card_; + Memory memory_; +}; +``` + +___ + +## `class Laptop` + +```cpp +class Laptop { +public: + void turnOn(); + void powerOff(); + void restart(); + void display(); + void getUserInput(); + +private: + Processor processor_; + Drive drive_; + Motherboard motherboard_; + GraphicsCard graphics_card_; + Memory memory_; + Screen screen_; + Keyboard keyboard_; +}; +``` + +___ + +## `class Tablet` + +```cpp +class Tablet { +public: + void turnOn(); + void powerOff(); + void restart(); + void display(); + void getUserInput(); + +private: + Processor processor_; + Drive drive_; + Motherboard motherboard_; + GraphicsCard graphics_card_; + Memory memory_; + Screen screen_; +}; +``` + +___ + + +## How to simplify the structure of our program? + +```cpp +class Computer { +public: + void turnOn(); + void powerOff(); + void restart(); + +protected: + Processor processor_; + Drive drive_; + Motherboard motherboard_; + GraphicsCard graphics_card_; + Memory memory_; +}; + + +class Laptop : public Computer { +public: + void display(); + void getUserInput(); + +private: + Screen screen_; + Keyboard keyboard_; +}; + + +class Tablet : public Computer { +public: + void display(); + void getUserInput(); + +private: + Screen screen_; +}; +``` + + +___ + +## Base classes and derived classes + +The class from which we inherit is called **base class**. + + +The class that it inherits is called **derived class**. + + +In other words, the class we inherit from is the parent class. + + +The class that inherits is child class. + + +___ + +### What about class methods `Laptop` and `Tablet`? + +#### Is it possible to distinguish another class? + + +```cpp +void display(); +void getUserInput(); +``` + + +___ + +## Classes `Screen` and `TouchScreen` + +Suppose we add a class `Screen`. This class displays the user interface in real time. + + +We also want to create a class that represents a touchscreen - `TouchScreen` which also allows you to read actions from the user and display them. + + +
+
+ +```cpp +class Screen { +public: + void display(); + +private: + void process(); + + Monitor monitor_; +}; +``` + + +
+
+ +```cpp +class TouchScreen { +public: + void display(); + void getUserInput(); + +private: + void process(); + void displayKeyboard(); + + Monitor monitor_; +}; +``` + + +
+
+ +### How to simplify the above code? + + +___ + +## Using inheritance to simplify code + +```cpp +class Screen { +public: + void display(); + +private: + void process(); + + Monitor monitor_; +}; +``` + + +```cpp +class TouchScreen : public Screen { +public: + void getUserInput(); + +private: + void displayKeyboard(); +}; +``` + + +___ + +## Multi-inheritance + +```cpp +class Screen { +public: + void display(); + +private: + void process(); + + Monitor monitor_; +}; + +class TouchScreen : public Screen { +public: + void getUserInput(); + +private: + void displayKeyboard(); +}; + +class Computer { +public: + void turnOn(); + void powerOff(); + void restart(); + +protected: + Processor processor_; + Drive drive_; + Motherboard motherboard_; + GraphicsCard graphics_card_; + Memory memory_; +}; + +class Laptop : public Computer, + public Screen { + Keyboard keyboard_; +}; + +class Tablet : public Computer, + public TouchScreen { +}; +``` + +___ + +## Multi-inheritance - disclaimer + +Multi-inheritance is inheriting from several base classes. + +The choice of implementation is up to the developer. + + +Multi-inheritance will not always be a better solution. + + +You should always consider whether inheriting from a specific class will simplify the program and whether it will not cause any complications in the further process of developing our program. + + +In the worst case, you will have to refactor the program 🙂 + + +___ + +## Inheritance - problems + +```cpp +struct Bird { + fly(); + makeSound(); +}; + +struct Penguin { + swim(); + makeSound(); +}; + +// Hummingbird is the type of bird which makes so little sound so it +// can be said that it makes no sound. +struct Hummingbird { + fly(); +}; +``` + +___ + + +## Inheritance - LSP principle + +If we now try to simplify the class through inheritance, the problem will arise: + +```cpp +struct Bird { + fly(); + makeSound(); +}; + +struct Penguin : public Bird { + fly(); // But I can't fly! + swim(); + makeSound(); +}; + +struct Hummingbird : public Bird { + fly(); + makeSound(); // But I don't make sound! +}; +``` + +We will make the situation even more difficult when we add more classes, such as Ostrich, in the future. Before the implementation, we always need to think about how to divide the responsibility into individual classes so that +avoid similar problems. + +___ + +### For the curious + +Read about the Liskov Substitution Principle (LSP). It tells how an object code should / should not be designed. This rule was broken in the last example. + +You can also read about all SOLID principles. + +___ + +## Q&A diff --git a/module2/presentation_inheritance.md b/module2/00_inheritance.pl.md similarity index 99% rename from module2/presentation_inheritance.md rename to module2/00_inheritance.pl.md index 0baa7910d..b4d909415 100644 --- a/module2/presentation_inheritance.md +++ b/module2/00_inheritance.pl.md @@ -297,7 +297,7 @@ Nie zawsze wielodziedziczenie będzie lepszym rozwiązaniem. Należy się zawsze zastanowić czy dziedziczenie po konkretnej klasie uprości nam program i czy nie będzie powodować żadnych komplikacji w dalszym procesie rozbudowy naszego programu. -Najwyżej trzeba będzie refaktoryzować program ;) +Najwyżej trzeba będzie refaktoryzować program 🙂 ___ diff --git a/module2/01_virtual.en.md b/module2/01_virtual.en.md new file mode 100644 index 000000000..aee31b68a --- /dev/null +++ b/module2/01_virtual.en.md @@ -0,0 +1,213 @@ + + +# Object oriented programming + +## Virtual methods, interfaces, abstract classes + + + Coders School + + +___ + + +## Pure virtual methods + +```cpp +class Bird { +public: + size_t getWeight(); + size_t getHeight(); + size_t getName(); + + // Pure virtual function without implementation + virtual void eat() = 0; + virtual void sleep() = 0; + +protected: + size_t weight_; + size_t height_; + std::string name_; +}; +``` + + +Methods `eat()` and `sleep()` are called pure virtual methods. Therefore we have `= 0;`. This means that we will not find their implementation for the `Bird` class. Classes that inherit from `Bird` will have to implement it themselves. + + +For now we will not talk about the meaning of the `virtual` keyword. The only thing you need to know for now is that for the method to be purely virtual `= 0;` it must be proceeded by `virtual`. + + +___ + + +## Interfaces + +One of the ideas for solving the problem of multi-inheritance is creating the so-called interfaces, their inheritance and overloading the implementation of methods from base classes. Interfaces define "skills" and are easy to connect with each other. + +```cpp +class Flyable { +public: + virtual void fly() = 0; + +private: + Wings wings_; +}; + +class Swimmable { +public: + virtual void swim() = 0; +}; + +class Soundable { +public: + virtual void makeSound() = 0; +}; +``` + + +___ + +## Use of interfaces + +```cpp +class Penguin : public Bird, public Swimmable { +public: + // Override from Bird + void eat() override; + void sleep() override; + + // Override from Swimmable + void swim() override; +}; + +class Hummingbird : public Bird, + public Flyable, + public Soundable { +public: + // Override from Bird + void eat() override; + void sleep() override; + + // Override from Soundable + void makeSound() override; + + // Override from Flyable + void fly() override; +}; + +class Goose : public Bird, + public Flyable, + public Soundable, + public Swimmable { +public: + // Override from Bird + void eat() override; + void sleep() override; + + // Override from Soundable + void makeSound() override; + + // Override from Flyable + void fly() override; + + // Override from Swimmable + void swim() override; +}; +``` + +___ + +## What is an interface? + +An interface is a set of functions that the class implementing it must implement. + + +An interface is a set of functions that a class that inherits from it must implement. + + +Failure to implement a purely virtual function is a linker error (undefined reference). + + +### Interface definition + + +A fully valid interface definition is the public part of a class / functional set. They can be methods, fields, or types, but most often we will use the interface words for public methods of a class. + + +[See the vector interface on cppreference.com](https://en.cppreference.com/w/cpp/container/vector) + + +There you will find a description of its public methods (member functions), internal types (member types), and loose functions that use it (non-member functions). + + +___ + +## Abstract class + +It's impossible to create an object of a class that has **at least one pure virtual function**. + + +A pure virtual function has no implementation, so there cannot be an object for which the linker does not find an implementation of one of its functions. + + +We can store a pointer to the type of this class, but we cannot create an instance of it (an object) because we do not have its behavior defined. + + +This class is called **an abstract class** and is only used to unify the interface, not to create objects. + + +Only an object of a derived class that implements all the missing methods can be created. + + +___ + +## Keywords `virtual` and `override` + +What are these keywords? What are they doing? About this in a moment 🙂 + + +___ + +## Q&A + +___ + +## Task 1 + +Convert class `Cargo` into an interface with 4 pure virtual methods. + +```cpp +virtual size_t getPrice() const = 0; +virtual std::string getName() const = 0; +virtual size_t getAmount() const = 0; +virtual size_t getBasePrice() const = 0; +``` + +___ + +## Task 1 cont. + +Create 3 classes derived from `Cargo`: + +* `Fruit` +* `Alcohol` +* `Item` + +Class `Fruit` should have an additional variable specifying the time to spoil and `operator--` which will subtract this time by 1. +Method `getPrice()` it should reduce the price accordingly with the spoilage time of our fruit. + +Class `Alcohol` should have an additional variable specifying the percentage of spirit. +Method `getPrice()` should be proportionally higher depending on the alcohol strength. +A base price should be set for 96% spirit. + +Class `Item` should have an additional enum variable specifying the rarity of the item (common, rare, epic, legendary). +Method `getPrice()` should be adequately calculated from the item's rarity level. + +___ + +## Exercise 2 + +Using a common base class `Cargo` try to store all the goods in one vector in the `Ship` class. + +Add a feature `void load(std::shared_ptr cargo)` that adds the goods and (for those willing) `void unload(Cargo* cargo)` that removes the item from the class object `Ship`. diff --git a/module2/presentation_virtual.md b/module2/01_virtual.pl.md similarity index 99% rename from module2/presentation_virtual.md rename to module2/01_virtual.pl.md index 44a01f5d6..262141ab9 100644 --- a/module2/presentation_virtual.md +++ b/module2/01_virtual.pl.md @@ -164,7 +164,7 @@ ___ ## Słowo `virtual` i `override` -Co to za słowa? Co one robią? O tym za chwilę ;) +Co to za słowa? Co one robią? O tym za chwilę 🙂 ___ diff --git a/module2/02_polymorphism.en.md b/module2/02_polymorphism.en.md new file mode 100644 index 000000000..42babf1f3 --- /dev/null +++ b/module2/02_polymorphism.en.md @@ -0,0 +1,367 @@ + + +# Object oriented programming + +## Polymorphism + + + Coders School + + +___ + +## Keyword `virtual` + +If we want a method to behave differently depending on the real type of the object when using pointers or references to the base class, then it should be marked with the keyword `virtual`. This is called virtual function. + +___ + + +## Non-virtual function + +```cpp +#include + +struct Bird { + void sing() { std::cout << "tweet, tweet\n"; } +}; + +struct Sparrow : Bird { + void sing() { std::cout << "chirp, chirp\n"; } +}; + +int main() { + Sparrow sparrow; + Bird& bird = sparrow; + bird.sing(); + return 0; +} +``` + +What will appear on the screen? + + +`tweet, tweet` + + +___ + + +## Virtual function + +```cpp +#include + +struct Bird { + virtual void sing() { std::cout << "tweet, tweet\n"; } +}; + +struct Sparrow : Bird { + void sing() { std::cout << "chirp, chirp\n"; } +}; + +int main() { + Sparrow sparrow; + Bird& bird = sparrow; + bird.sing(); + return 0; +} +``` + +What will appear on the screen? + + +`chirp, chirp` + + +[Check it out at ideone.com](https://ideone.com/yW43Tq) + + +___ + +## Keyword `override` + +If in the derived class **we overwrite** virtual method, i.e. changing its behavior, you should add a keyword `override`. + + +```cpp +class Interface { +public: + virtual void doSth() = 0; +}; + +class SomeClass : public Interface { +public: + void doSth() override; // there should be an implementation in cpp file +}; + +int main() { + // Interface interface; // Compilation error, Interface is pure virtual + SomeClass someClass; // OK + Interface* interface = &someClass; // OK, we hold a pointer +} +``` + + +___ + +### A little note + +`override` is optional. If we do not give it after the signature of the derived class function then the base class method will be overwritten anyway. + + +Its use, however, is a good practice, because thanks to it the compiler will check whether we are actually overwriting the method from the base class and if not, the program will not compile. + + +Without `override` a new method could be created in the derived class that does not overwrite anything from the base class. + + +**We overwrite** virtual methods, not overload them. + + +___ + +## Overwriting methods - `override` + +Returning to the bird example, classes `Penguin`, `Hummingbird` and `Goose` are derived classes that inherit from certain base classes like `Bird`, `Flyable`, `Soundable`, `Swimmable` and override some of their methods, such as: + +* void eat() override +* void sleep() override +* void makeSound() override +* void fly() override +* void swim() override + +Overwriting such methods means that we can change their implementations. + + +___ + +## `override` + +```cpp +class Soundable { +public: + virtual void makeSound() = 0; +}; +``` + +```cpp +class Goose : public Soundable { +public: + void makeSound() override { std::cout << "Honk! Honk!"; } +}; +``` + +```cpp +class Hen : public Soundable { +public: + void makeSound() override { std::cout << "Cluck! Cluck!"; } +}; +``` + +```cpp +class Duck : public Soundable { +public: + void makeSound() override { std::cout << "Quack! Quack!"; } +}; +``` + +___ + +## Common base class + +Because the common parent of all classes is the class `Soundable` we can store type pointers in a container `Soundable`. + +```cpp +std::vector> birds_; +``` + +### What data will we get on the output? + +```cpp +std::vector> birds_; +birds_.push_back(std::make_shared()); +birds_.push_back(std::make_shared()); +birds_.push_back(std::make_shared()); + +std::cout << birds_[0]->makeSound() << '\n'; +std::cout << birds_[1]->makeSound() << '\n'; +std::cout << birds_[2]->makeSound() << '\n'; +``` + + +___ + +## Polymorphism + +The phenomenon we just observed is called polymorphism. + +Polymorphism allows a function to take various forms (implementations), as in the example. + + +Therefore, if we create objects `Goose`, `Hen` and `Duck`, depending on the object, its version of the method `makeSound` will be called. + + +Polymorphism turns on when we have virtual functions and we use pointers or references to the base type. + + +### Who has played or read The Witcher? + + +___ + +## Doppler 🙂 + +In the universe created by our native writer Andrzej Sapkowski, there is an intriguing and interesting race called the Dopplers. + + +This race can take the form of various life forms, it can become a human, an elf, or a dwarf. It changes its characteristics like voice, hair color and even clothes! + + +Despite the fact that this race is of the Doppler type, it can in various circumstances impersonate other races such as elf, dwarf or human. + + +From the C++ point of view, our Doppler is subject to the phenomenon of polymorphism. + + +___ + + +```cpp +class Doppler { +public: + virtual sayHello() { std::cout << "I'm Doppler!"; } +}; + +class Dwarf : public Doppler { +public: + virtual sayHello() { std::cout << "I'm Dwarf!"; } +}; + +class Elf : public Doppler { +public: + virtual sayHello() { std::cout << "I'm Elf!"; } +}; + +class Human : public Doppler { +public: + virtual sayHello() { std::cout << "I'm Human!"; } +}; + +int main() { + std::shared_ptr doppler1 = std::make_shared(); + std::shared_ptr doppler2 = std::make_shared(); + std::shared_ptr doppler3 = std::make_shared(); + + std::cout << doppler1->sayHello() << '\n'; + std::cout << doppler2->sayHello() << '\n'; + std::cout << doppler3->sayHello() << '\n'; +} +``` + + + +As we can see, our Doppler can take various forms and behave like them. The pointer is Doppler, but the program knows well when a Doppler impersonates a human, a dwarf, and an elf. + +___ + + +## Non-virtual destructors + +Very important when creating virtual methods and inheritance is creating virtual destructors. +If we use the goodness of polymorphism and we don't mark the destructor as `virtual` the destructor will not be called. + +```cpp +#include +#include + +class Parent { +public: + Parent() { std::cout << "PARENT C'tor called\n"; } + ~Parent() { std::cout << "PARENT D'tor caller\n"; } +}; + +class Child : public Parent { +public: + Child() { std::cout << "CHILD C'tor called\n"; } + ~Child() { std::cout << "CHILD D'tor caller\n"; } +}; + +int main() { + Child child; // ok, object on stack, not a pointer +} +``` + +___ + +## Non-virtual destructors - problem + +```cpp +#include +#include +#include + +class Parent { +public: + Parent() { std::cout << "PARENT C'tor called\n"; } + ~Parent() { std::cout << "PARENT D'tor caller\n"; } +}; + +class Child : public Parent { +public: + Child() { std::cout << "CHILD C'tor called\n"; } + ~Child() { std::cout << "CHILD D'tor caller\n"; } +}; + +int main() { + // Problem + std::unique_ptr child = std::make_unique(); + + // But shared_ptr will cleanup properly + std::shared_ptr child2 = std::make_shared(); +} +``` + +___ + +## Virtual destructor + +```cpp +#include +#include +#include + +class Parent { +public: + Parent() { std::cout << "PARENT C'tor called\n"; } + virtual ~Parent() { std::cout << "PARENT D'tor caller\n"; } +}; + +class Child : public Parent { +public: + Child() { std::cout << "CHILD C'tor called\n"; } + ~Child() override { std::cout << "CHILD D'tor caller\n"; } +}; + +int main() { + std::unique_ptr child2 = std::make_unique(); +} +``` + +___ + +## Q&A + +___ + +## Exercise 3 + +Write a class `DryFruit` that will inherit from the class `Fruit`. + +This class should override methods `getPrice()`, `getName()` and `operator--`. + +`operator--` should subtract consumption once every 10 times. + +Method `getPrice()` should return three times the value of the base price. + +Test polymorphic calls and share your conclusions. diff --git a/module2/presentation_polymorphism.md b/module2/02_polymorphism.pl.md similarity index 99% rename from module2/presentation_polymorphism.md rename to module2/02_polymorphism.pl.md index 5e46c6f19..e6c702186 100644 --- a/module2/presentation_polymorphism.md +++ b/module2/02_polymorphism.pl.md @@ -210,7 +210,7 @@ Polimorfizm włącza się, gdy mamy funkcje wirtualne i używamy wskaźników lu ___ -## Doppler :) +## Doppler 🙂 W uniwersum wykreowanym przez naszego rodzimego pisarza Andrzeja Sapkowskiego, występuje pewna intrygująca i ciekawa rasa zwana Dopplerami. diff --git a/module2/03_static.en.md b/module2/03_static.en.md new file mode 100644 index 000000000..a9225370e --- /dev/null +++ b/module2/03_static.en.md @@ -0,0 +1,91 @@ + + +# Object oriented programming + +## Static variables and functions + + + Coders School + + +___ + + +## "Class variable or constant" + +Sometimes we would like to assign some permanent trait to a class. +Not specific objects, but a class itself. +For example, each class object is named "Object". + + +```cpp +class Object { +public: + std::string GetName() const { return name_; } + +private: + const std::string name_ = "Object"; +}; +``` + + +In order to get the name of this object, we need to create the object first and then call it `getName()`. + + +```cpp +int main() { + Object obj; + std::cout << obj.getName() << '\n'; +} +``` + + +Even if the object would take up a lot of memory and we only want its name, we still have to create it, because only on it we can call the method `getName()`. + + +___ + + +## `static` + +The solution to this nuisance is `static`. Moreover, we can solve this problem in two ways. We don't have to create an object this way to get to the class attribute, which is its name. + +```cpp +class ObjectA { +public: + static std::string getName() { return "ObjectA"; } +}; + +class ObjectB { +public: + static std::string name_; +}; + +std::string ObjectB::name_{"ObjectB"}; + +int main() { + std::cout << ObjectA::getName() << '\n'; + std::cout << ObjectB::name_ << '\n'; + + return 0; +} +``` + + + + +___ + +## Q&A + +___ + +## Task 4 + +Convert base class `Coordinates` so that it has a static function + +```cpp +static size_t distance(const Coordinates& lhs, const Coordinates& rhs) +``` + +This function should return the distance between two positions. diff --git a/module2/presentation_static.md b/module2/03_static.pl.md similarity index 100% rename from module2/presentation_static.md rename to module2/03_static.pl.md diff --git a/module2/04_homework.en.md b/module2/04_homework.en.md new file mode 100644 index 000000000..ef2493624 --- /dev/null +++ b/module2/04_homework.en.md @@ -0,0 +1,148 @@ + + +# Object oriented programming + +## Summary + + + Coders School + + +___ + +## What do you remember from today? + +### Write as many keywords as possible in the chat + + +1. Inheritance +2. multi-inheritance +3. virtual functions +4. pure virtual functions +5. abstract classes +6. interfaces +7. polymorphism +8. static fields and methods + +___ + +### Pre-work + +* Find out what the diamond problem is +* Read about SOLID rules for writing good object-oriented code +* Reading about design patterns with examples in C++ - [refactoring.guru](https://refactoring.guru/design-patterns) +* Try Copy & Paste to add the cmake build system to your project. For this, have a look at the homework so far and the CMakeLists.txt file. + +___ + +## Group project + +Use the code written during the class. You can also use the code in the [solutions](solutions) directory + +Group project - continuation. You can change the group if you want 🙂 + +___ + +## Organization of work + +* How was your daily? +* Is Code Review neglected? +* Is the collaboration going smoothly? +* Do yourself a retrospective 🙂 + +___ + +### Punctation + +* The first 3 tasks - 5 points +* tasks 4, 5, 6 - 8 points +* 20 points for all 6 items delivered before 05/07/2020 (Sunday) by 23:59 +* no bonus points for delivering only some of the tasks before 05.07 +* 6 points for group work for each person in the group. + +___ + +## Task 1 + +Write a class `Store` that will allow you to make purchases. Use the enum and functions below. + +```cpp +enum class Response {done, lack_of_money, lack_of_cargo, lack_of_space}; + +Response buy(Cargo* cargo, size_t amount, Player* player); +Response sell(Cargo* cargo, size_t amount, Player* player); +``` + +___ + +## Exercise 2 + +In classes `Alcohol`, `Fruit`, `Item` add the missing methods and their implementations. + +```cpp +// override from Cargo +size_t getPrice() const override; +std::string getName() const override { return name_; } +size_t getAmount() const override { return amount_; } +size_t getBasePrice() const override { return base_price_; } +Cargo& operator+=(size_t amount) override; +Cargo& operator-=(size_t amount) override; +bool operator==(Cargo& cargo) const override; +``` + +___ + +## Exercise 3 + +Add to the class `Ship`, `Cargo` and `Store` method `nextDay()` + +* Class `Ship`: The method should subtract 1 coin for each crew member. +* Class `Cargo`: The method should spoil the goods. +* Class `Store`: The method should change the quantity of goods in stores. + +___ + +## Task 4 (for the ambitious) + +Try to write a class `Time` which will be responsible for time management in the game. + +This class should inform other classes, such as `Cargo`, `Ship`, `Store` about the expiry of each day. + +Read about [`Observer`](https://refactoring.guru/design-patterns/observer) design pattern. + +___ + +## Task 5 (for the ambitious) + +Write a friend operator that writes out to stream + +```cpp +friend std::ostream& operator<<(std::ostream& out, const Store& store); +``` + +It should write out the goods that are in a given store in an accessible way. + +___ + +## Task 6 (for the ambitious) + +Write a class `Game` that will manage the entire game. + +Add to it public method `startGame()`. + +Finally, the main file should look like this: + +```cpp +#include "Game.hpp" + +constexpr size_t start_money = 1'000; +constexpr size_t game_days = 100; +constexpr size_t final_goal = 2'000; + +int main() { + Game game(start_money, game_days, final_goal); + game.startGame(); + + return 0; +} +``` diff --git a/module3/presentation_homework.md b/module2/04_homework.pl.md similarity index 98% rename from module3/presentation_homework.md rename to module2/04_homework.pl.md index 13c848d34..01ab97059 100644 --- a/module3/presentation_homework.md +++ b/module2/04_homework.pl.md @@ -39,7 +39,7 @@ ___ Wykorzystajcie kod napisany podczas zajęć. Możecie też skorzystać z kodu w katalogu [solutions](solutions) -Projekt grupowy - kontynuacja. Możecie zmienić grupę jeśli chcecie ;) +Projekt grupowy - kontynuacja. Możecie zmienić grupę jeśli chcecie 🙂 ___ @@ -48,7 +48,7 @@ ___ * Jak wyglądało wasze daily? * Czy Code Review nie jest zaniedbane? * Czy współpraca idzie gładko? -* Zróbcie sobie retrospektywę :) +* Zróbcie sobie retrospektywę 🙂 ___ diff --git a/module2/05_solutions.en.md b/module2/05_solutions.en.md new file mode 100644 index 000000000..d74d1dc3c --- /dev/null +++ b/module2/05_solutions.en.md @@ -0,0 +1,261 @@ + + +# Object oriented programming + +## Examples of solutions + + + Coders School + + +___ + +### Task 1 + +Cargo.hpp + +```cpp +bool operator==(const Cargo& cargo) const; +``` + +Cargo.cpp + +```cpp +bool Cargo::operator==(const Cargo& cargo) const { + return Cargo.getBasePrice() == base_price_ && Cargo.getName() == name_; +} +``` + +___ + +### Exercise 2 + +Cargo.hpp + +```cpp +std::string getName() const; +size_t getAmount() const; +size_t getBasePrice() const; +``` + +Cargo.cpp + +```cpp +std::string Cargo::getName() const { return name_; } +size_t Cargo::getAmount() const { return amount_; } +size_t Cargo::getBasePrice() const { return base_price_; } +``` + +___ + +### Task 3 #1 + +Island.hpp + +```cpp +#include +#include + +#include "Store.hpp" + +class Time; + +// Class describes position of island and available store. +class Island { +public: + class Coordinates { + public: + Coordinates() = default; + Coordinates(size_t pos_x, size_t pos_y) + : pos_x_(pos_x), pos_y_(pos_y) {} + + bool operator==(const Coordinates& rhs) const { + return this->pos_x_ == rhs.pos_x_ && this->pos_y_ == rhs.pos_y_; + } + + private: + const size_t pos_x_{0}; + const size_t pos_y_{0}; + }; + + Island() {} + Island(size_t pos_x, size_t pos_y, Time* time); + Coordinates getCoordinates() const { return position_; } + Store* getStore() const { return store_.get(); } + +private: + std::unique_ptr store_; + Coordinates position_; +}; +``` + +___ + +### Task 3 #2 + +Island.cpp + +```cpp +#include "GTime.hpp" +#include "Island.hpp" + +Island::Island(size_t pos_x, size_t pos_y, Time* time) + : position_(Coordinates(pos_x, pos_y)), + store_(std::make_unique(time)) { +} +``` + +___ + +## Task 4/5/6 #1 + +Map.hpp + +```cpp +class Time; + +// Class responsible for map generation which will be used to travel. +class Map { +public: + Map(Time* time); + void travel(Island* destination); + Island* getIsland(const Island::Coordinates& coordinate); + Island* getCurrentPosition() const { return current_position_; } + friend std::ostream& operator<<(std::ostream& out, const Map& map); + +private: + Island* current_position_; + std::vector islands_; +}; +``` + +___ + +### Task 4/5/6 #2 + +Map.cpp + +```cpp +constexpr size_t kIslandNum = 10; +constexpr size_t kWidth = 50; +constexpr size_t kHeight = 50; + +Map::Map(Time* time) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> widthGen(0, kWidth); + std::uniform_int_distribution<> heightGen(0, kHeight); + std::vector islands(kIslandNum); + std::vector> usedPositions; + + // Generate map + for (size_t i = 0; i < kIslandNum; ++i) { + while (true) { + size_t x = widthGen(gen); + size_t y = heightGen(gen); + if (std::find_if(begin(usedPositions), + end(usedPositions), + [x, y](const auto& pos) { + return pos.first == x && pos.second == y; + }) == std::end(usedPositions)) { + usedPositions.push_back({x, y}); + islands_.push_back(Island(x, y, time)); + break; + } + } + } + + current_position_ = &islands_.front(); +} + +Island* Map::getIsland(const Island::Coordinates& coordinate) { + auto island = std::find_if(std::begin(islands_), + std::end(islands_), + [&coordinate](const Island& island) { + return coordinate == island.GetCoordinates(); + }); + return island != std::end(islands_) ? &*island : nullptr; +} + +void Map::travel(Island* destination) { + current_position_ = destination; +} +``` + +___ + +### Task 7/8 #1 + +Player.hpp + +```cpp +#include + +#include "Cargo.hpp" +#include "Ship.hpp" + +class Time; + +// Class is responsible for every action made by player +class Player { +public: + Player(size_t money, Time* time); + virtual ~Player() = default; + + virtual size_t getAvailableSpace() const; + virtual size_t getMoney() const; + virtual size_t getSpeed() const; + virtual Cargo* getCargo(size_t index) const; + +private: + std::unique_ptr ship_; + size_t money_; + size_t available_space_; +}; + +``` + +___ + +### Task 7/8 #2 + +Player.cpp + +```cpp +constexpr size_t kCapacity = 100; +constexpr size_t kCrew = 50; +constexpr size_t kSpeed = 10; +constexpr char kName[] = "BLACK WIDOW"; +constexpr size_t kId = 10; + +Player::Player(size_t money, Time* time) + : ship_(std::make_unique(kCapacity, kCrew, kSpeed, kName, kId, time, this)), + money_(money), + available_space_(kCapacity) { +} + +size_t Player::getMoney() const { + return money_; +} + +size_t Player::getSpeed() const { + return ship_->getSpeed(); +} + +Cargo* Player::getCargo(size_t index) const { + return ship_->getCargo(index); +} + +size_t Player::getAvailableSpace() const { + size_t total_cargo_amount = 0; + for (const auto cargo : ship_->getCargos()) { + total_cargo_amount += cargo->getAmount(); + } + available_space_ = ship_->getCapacity() - total_cargo_amount; + return available_space_; +} +``` + +___ + +## Q&A diff --git a/module2/presentation_solutions.md b/module2/05_solutions.pl.md similarity index 100% rename from module2/presentation_solutions.md rename to module2/05_solutions.pl.md diff --git a/module2/index.en.html b/module2/index.en.html new file mode 100644 index 000000000..9b96f5238 --- /dev/null +++ b/module2/index.en.html @@ -0,0 +1,153 @@ + + + + + + + Object Oriented Programming - Coders School + + + + + + + + + + + + + + + +
+
+
+
+ +

OOP #2

+

Object Oriented Programming #2

+ + Coders School + +

Mateusz Adamski

+

Łukasz Ziobroń

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+ +

Coders School

+ Coders School + +
+
+
+ + + + + + diff --git a/module2/index.html b/module2/index.pl.html similarity index 88% rename from module2/index.html rename to module2/index.pl.html index eba0b5481..0f554100d 100644 --- a/module2/index.html +++ b/module2/index.pl.html @@ -4,7 +4,7 @@ - Object Oriented Programming - Coders School + Programowanie Obiektowe - Coders School @@ -32,7 +32,7 @@

OOP #2

-

Object-Oriented Programming #2

+

Programowanie Obiektowe #2

Coders School @@ -64,9 +64,7 @@

Łukasz Ziobroń

## Zadania - Repo GH `coders-school/object-oriented-programming` - - [https://github.com/coders-school/object-oriented-programming/tree/master/module2](https://github.com/coders-school/object-oriented-programming/tree/master/module2) + [Repo GH `coders-school/object-oriented-programming`](https://github.com/coders-school/object-oriented-programming/tree/master/module2)
@@ -97,27 +95,27 @@

Łukasz Ziobroń

You can change the port by using npm start -- --port=8001. --> -
-
-
-
-
- diff --git a/module3/00_solutions.en.md b/module3/00_solutions.en.md new file mode 100644 index 000000000..0812b6589 --- /dev/null +++ b/module3/00_solutions.en.md @@ -0,0 +1,267 @@ + + +# Object oriented programming + +## Examples of solutions + + + Coders School + + +___ + +## Disclaimer + +In PDF, these solutions can be partially truncated. Go to the lessons on the platform or on GitHub to see them fully. + +___ + +### Task 1 + +Cargo.hpp + +```cpp +bool operator==(const Cargo& cargo) const; +``` + +Cargo.cpp + +```cpp +bool Cargo::operator==(const Cargo& cargo) const { + return Cargo.getBasePrice() == base_price_ && Cargo.getName() == name_; +} +``` + +___ + +### Exercise 2 + +Cargo.hpp + +```cpp +std::string getName() const; +size_t getAmount() const; +size_t getBasePrice() const; +``` + +Cargo.cpp + +```cpp +std::string Cargo::getName() const { return name_; } +size_t Cargo::getAmount() const { return amount_; } +size_t Cargo::getBasePrice() const { return base_price_; } +``` + +___ + +### Task 3 # 1 + +Island.hpp + +```cpp +#include +#include + +#include "Store.hpp" + +class Time; + +// Class describes position of island and available store. +class Island { +public: + class Coordinates { + public: + Coordinates() = default; + Coordinates(size_t pos_x, size_t pos_y) + : pos_x_(pos_x), pos_y_(pos_y) {} + + bool operator==(const Coordinates& lhs) const { + return this->pos_x_ == lhs.pos_x_ && this->pos_y_ == lhs.pos_y_; + } + + private: + const size_t pos_x_{0}; + const size_t pos_y_{0}; + }; + + Island() {} + Island(size_t pos_x, size_t pos_y, Time* time); + Coordinates getCoordinates() const { return position_; } + Store* getStore() const { return store_.get(); } + +private: + std::unique_ptr store_; + Coordinates position_; +}; +``` + +___ + +### Task 3 # 2 + +Island.cpp + +```cpp +#include "GTime.hpp" +#include "Island.hpp" + +Island::Island(size_t pos_x, size_t pos_y, Time* time) + : position_(Coordinates(pos_x, pos_y)), + store_(std::make_unique(time)) { +} +``` + +___ + +## Task 4/5/6 # 1 + +Map.hpp + +```cpp +class Time; + +// Class responsible for map generation which will be used to travel. +class Map { +public: + Map(Time* time); + void travel(Island* destination); + Island* getIsland(const Island::Coordinates& coordinate); + Island* getCurrentPosition() const { return current_position_; } + friend std::ostream& operator<<(std::ostream& out, const Map& map); + +private: + Island* current_position_; + std::vector islands_; +}; +``` + +___ + +### Task 4/5/6 # 2 + +Map.cpp + +```cpp +constexpr size_t kIslandNum = 10; +constexpr size_t kWidth = 50; +constexpr size_t kHeight = 50; + +Map::Map(Time* time) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> widthGen(0, kWidth); + std::uniform_int_distribution<> heightGen(0, kHeight); + std::vector islands(kIslandNum); + std::vector> usedPositions; + + // Generate map + for (size_t i = 0; i < kIslandNum; ++i) { + while (true) { + size_t x = widthGen(gen); + size_t y = heightGen(gen); + if (std::find_if(begin(usedPositions), + end(usedPositions), + [x, y](const auto& pos) { + return pos.first == x && pos.second == y; + }) == std::end(usedPositions)) { + usedPositions.push_back({x, y}); + islands_.push_back(Island(x, y, time)); + break; + } + } + } + + current_position_ = &islands_.front(); +} + +Island* Map::getIsland(const Island::Coordinates& coordinate) { + auto island = std::find_if(std::begin(islands_), + std::end(islands_), + [&coordinate](const Island& island) { + return coordinate == island.GetCoordinates(); + }); + return island != std::end(islands_) ? &*island : nullptr; +} + +void Map::travel(Island* destination) { + current_position_ = destination; +} +``` + +___ + +### Task 7/8 # 1 + +Player.hpp + +```cpp +#include + +#include "Cargo.hpp" +#include "Ship.hpp" + +class Time; + +// Class is responsible for every action made by player +class Player { +public: + Player(size_t money, Time* time); + virtual ~Player() = default; + + virtual size_t getAvailableSpace() const; + virtual size_t getMoney() const; + virtual size_t getSpeed() const; + virtual Cargo* getCargo(size_t index) const; + +private: + std::unique_ptr ship_; + size_t money_; + size_t available_space_; +}; + +``` + +___ + +### Task 7/8 # 2 + +Player.cpp + +```cpp +constexpr size_t kCapacity = 100; +constexpr size_t kCrew = 50; +constexpr size_t kSpeed = 10; +constexpr char kName[] = "BLACK WIDOW"; +constexpr size_t kId = 10; + +Player::Player(size_t money, Time* time) + : ship_(std::make_unique(kCapacity, kCrew, kSpeed, kName, kId, time, this)), + money_(money), + available_space_(kCapacity) { +} + +size_t Player::getMoney() const { + return money_; +} + +size_t Player::getSpeed() const { + return ship_->getSpeed(); +} + +Cargo* Player::getCargo(size_t index) const { + return ship_->getCargo(index); +} + +size_t Player::getAvailableSpace() const { + available_space_ = 0; + for (const auto cargo : ship_->getCargos()) { + available_space_ += cargo->getAmount(); + } + + return available_space_; +} +``` + +___ + +## Q&A diff --git a/module3/presentation_solutions.md b/module3/00_solutions.pl.md similarity index 100% rename from module3/presentation_solutions.md rename to module3/00_solutions.pl.md diff --git a/module3/01_polymorphism.en.md b/module3/01_polymorphism.en.md new file mode 100644 index 000000000..42babf1f3 --- /dev/null +++ b/module3/01_polymorphism.en.md @@ -0,0 +1,367 @@ + + +# Object oriented programming + +## Polymorphism + + + Coders School + + +___ + +## Keyword `virtual` + +If we want a method to behave differently depending on the real type of the object when using pointers or references to the base class, then it should be marked with the keyword `virtual`. This is called virtual function. + +___ + + +## Non-virtual function + +```cpp +#include + +struct Bird { + void sing() { std::cout << "tweet, tweet\n"; } +}; + +struct Sparrow : Bird { + void sing() { std::cout << "chirp, chirp\n"; } +}; + +int main() { + Sparrow sparrow; + Bird& bird = sparrow; + bird.sing(); + return 0; +} +``` + +What will appear on the screen? + + +`tweet, tweet` + + +___ + + +## Virtual function + +```cpp +#include + +struct Bird { + virtual void sing() { std::cout << "tweet, tweet\n"; } +}; + +struct Sparrow : Bird { + void sing() { std::cout << "chirp, chirp\n"; } +}; + +int main() { + Sparrow sparrow; + Bird& bird = sparrow; + bird.sing(); + return 0; +} +``` + +What will appear on the screen? + + +`chirp, chirp` + + +[Check it out at ideone.com](https://ideone.com/yW43Tq) + + +___ + +## Keyword `override` + +If in the derived class **we overwrite** virtual method, i.e. changing its behavior, you should add a keyword `override`. + + +```cpp +class Interface { +public: + virtual void doSth() = 0; +}; + +class SomeClass : public Interface { +public: + void doSth() override; // there should be an implementation in cpp file +}; + +int main() { + // Interface interface; // Compilation error, Interface is pure virtual + SomeClass someClass; // OK + Interface* interface = &someClass; // OK, we hold a pointer +} +``` + + +___ + +### A little note + +`override` is optional. If we do not give it after the signature of the derived class function then the base class method will be overwritten anyway. + + +Its use, however, is a good practice, because thanks to it the compiler will check whether we are actually overwriting the method from the base class and if not, the program will not compile. + + +Without `override` a new method could be created in the derived class that does not overwrite anything from the base class. + + +**We overwrite** virtual methods, not overload them. + + +___ + +## Overwriting methods - `override` + +Returning to the bird example, classes `Penguin`, `Hummingbird` and `Goose` are derived classes that inherit from certain base classes like `Bird`, `Flyable`, `Soundable`, `Swimmable` and override some of their methods, such as: + +* void eat() override +* void sleep() override +* void makeSound() override +* void fly() override +* void swim() override + +Overwriting such methods means that we can change their implementations. + + +___ + +## `override` + +```cpp +class Soundable { +public: + virtual void makeSound() = 0; +}; +``` + +```cpp +class Goose : public Soundable { +public: + void makeSound() override { std::cout << "Honk! Honk!"; } +}; +``` + +```cpp +class Hen : public Soundable { +public: + void makeSound() override { std::cout << "Cluck! Cluck!"; } +}; +``` + +```cpp +class Duck : public Soundable { +public: + void makeSound() override { std::cout << "Quack! Quack!"; } +}; +``` + +___ + +## Common base class + +Because the common parent of all classes is the class `Soundable` we can store type pointers in a container `Soundable`. + +```cpp +std::vector> birds_; +``` + +### What data will we get on the output? + +```cpp +std::vector> birds_; +birds_.push_back(std::make_shared()); +birds_.push_back(std::make_shared()); +birds_.push_back(std::make_shared()); + +std::cout << birds_[0]->makeSound() << '\n'; +std::cout << birds_[1]->makeSound() << '\n'; +std::cout << birds_[2]->makeSound() << '\n'; +``` + + +___ + +## Polymorphism + +The phenomenon we just observed is called polymorphism. + +Polymorphism allows a function to take various forms (implementations), as in the example. + + +Therefore, if we create objects `Goose`, `Hen` and `Duck`, depending on the object, its version of the method `makeSound` will be called. + + +Polymorphism turns on when we have virtual functions and we use pointers or references to the base type. + + +### Who has played or read The Witcher? + + +___ + +## Doppler 🙂 + +In the universe created by our native writer Andrzej Sapkowski, there is an intriguing and interesting race called the Dopplers. + + +This race can take the form of various life forms, it can become a human, an elf, or a dwarf. It changes its characteristics like voice, hair color and even clothes! + + +Despite the fact that this race is of the Doppler type, it can in various circumstances impersonate other races such as elf, dwarf or human. + + +From the C++ point of view, our Doppler is subject to the phenomenon of polymorphism. + + +___ + + +```cpp +class Doppler { +public: + virtual sayHello() { std::cout << "I'm Doppler!"; } +}; + +class Dwarf : public Doppler { +public: + virtual sayHello() { std::cout << "I'm Dwarf!"; } +}; + +class Elf : public Doppler { +public: + virtual sayHello() { std::cout << "I'm Elf!"; } +}; + +class Human : public Doppler { +public: + virtual sayHello() { std::cout << "I'm Human!"; } +}; + +int main() { + std::shared_ptr doppler1 = std::make_shared(); + std::shared_ptr doppler2 = std::make_shared(); + std::shared_ptr doppler3 = std::make_shared(); + + std::cout << doppler1->sayHello() << '\n'; + std::cout << doppler2->sayHello() << '\n'; + std::cout << doppler3->sayHello() << '\n'; +} +``` + + + +As we can see, our Doppler can take various forms and behave like them. The pointer is Doppler, but the program knows well when a Doppler impersonates a human, a dwarf, and an elf. + +___ + + +## Non-virtual destructors + +Very important when creating virtual methods and inheritance is creating virtual destructors. +If we use the goodness of polymorphism and we don't mark the destructor as `virtual` the destructor will not be called. + +```cpp +#include +#include + +class Parent { +public: + Parent() { std::cout << "PARENT C'tor called\n"; } + ~Parent() { std::cout << "PARENT D'tor caller\n"; } +}; + +class Child : public Parent { +public: + Child() { std::cout << "CHILD C'tor called\n"; } + ~Child() { std::cout << "CHILD D'tor caller\n"; } +}; + +int main() { + Child child; // ok, object on stack, not a pointer +} +``` + +___ + +## Non-virtual destructors - problem + +```cpp +#include +#include +#include + +class Parent { +public: + Parent() { std::cout << "PARENT C'tor called\n"; } + ~Parent() { std::cout << "PARENT D'tor caller\n"; } +}; + +class Child : public Parent { +public: + Child() { std::cout << "CHILD C'tor called\n"; } + ~Child() { std::cout << "CHILD D'tor caller\n"; } +}; + +int main() { + // Problem + std::unique_ptr child = std::make_unique(); + + // But shared_ptr will cleanup properly + std::shared_ptr child2 = std::make_shared(); +} +``` + +___ + +## Virtual destructor + +```cpp +#include +#include +#include + +class Parent { +public: + Parent() { std::cout << "PARENT C'tor called\n"; } + virtual ~Parent() { std::cout << "PARENT D'tor caller\n"; } +}; + +class Child : public Parent { +public: + Child() { std::cout << "CHILD C'tor called\n"; } + ~Child() override { std::cout << "CHILD D'tor caller\n"; } +}; + +int main() { + std::unique_ptr child2 = std::make_unique(); +} +``` + +___ + +## Q&A + +___ + +## Exercise 3 + +Write a class `DryFruit` that will inherit from the class `Fruit`. + +This class should override methods `getPrice()`, `getName()` and `operator--`. + +`operator--` should subtract consumption once every 10 times. + +Method `getPrice()` should return three times the value of the base price. + +Test polymorphic calls and share your conclusions. diff --git a/module3/presentation_polymorphism.md b/module3/01_polymorphism.pl.md similarity index 100% rename from module3/presentation_polymorphism.md rename to module3/01_polymorphism.pl.md diff --git a/module3/02_static.en.md b/module3/02_static.en.md new file mode 100644 index 000000000..a9225370e --- /dev/null +++ b/module3/02_static.en.md @@ -0,0 +1,91 @@ + + +# Object oriented programming + +## Static variables and functions + + + Coders School + + +___ + + +## "Class variable or constant" + +Sometimes we would like to assign some permanent trait to a class. +Not specific objects, but a class itself. +For example, each class object is named "Object". + + +```cpp +class Object { +public: + std::string GetName() const { return name_; } + +private: + const std::string name_ = "Object"; +}; +``` + + +In order to get the name of this object, we need to create the object first and then call it `getName()`. + + +```cpp +int main() { + Object obj; + std::cout << obj.getName() << '\n'; +} +``` + + +Even if the object would take up a lot of memory and we only want its name, we still have to create it, because only on it we can call the method `getName()`. + + +___ + + +## `static` + +The solution to this nuisance is `static`. Moreover, we can solve this problem in two ways. We don't have to create an object this way to get to the class attribute, which is its name. + +```cpp +class ObjectA { +public: + static std::string getName() { return "ObjectA"; } +}; + +class ObjectB { +public: + static std::string name_; +}; + +std::string ObjectB::name_{"ObjectB"}; + +int main() { + std::cout << ObjectA::getName() << '\n'; + std::cout << ObjectB::name_ << '\n'; + + return 0; +} +``` + + + + +___ + +## Q&A + +___ + +## Task 4 + +Convert base class `Coordinates` so that it has a static function + +```cpp +static size_t distance(const Coordinates& lhs, const Coordinates& rhs) +``` + +This function should return the distance between two positions. diff --git a/module3/presentation_static.md b/module3/02_static.pl.md similarity index 100% rename from module3/presentation_static.md rename to module3/02_static.pl.md diff --git a/module3/03_homework.en.md b/module3/03_homework.en.md new file mode 100644 index 000000000..ef2493624 --- /dev/null +++ b/module3/03_homework.en.md @@ -0,0 +1,148 @@ + + +# Object oriented programming + +## Summary + + + Coders School + + +___ + +## What do you remember from today? + +### Write as many keywords as possible in the chat + + +1. Inheritance +2. multi-inheritance +3. virtual functions +4. pure virtual functions +5. abstract classes +6. interfaces +7. polymorphism +8. static fields and methods + +___ + +### Pre-work + +* Find out what the diamond problem is +* Read about SOLID rules for writing good object-oriented code +* Reading about design patterns with examples in C++ - [refactoring.guru](https://refactoring.guru/design-patterns) +* Try Copy & Paste to add the cmake build system to your project. For this, have a look at the homework so far and the CMakeLists.txt file. + +___ + +## Group project + +Use the code written during the class. You can also use the code in the [solutions](solutions) directory + +Group project - continuation. You can change the group if you want 🙂 + +___ + +## Organization of work + +* How was your daily? +* Is Code Review neglected? +* Is the collaboration going smoothly? +* Do yourself a retrospective 🙂 + +___ + +### Punctation + +* The first 3 tasks - 5 points +* tasks 4, 5, 6 - 8 points +* 20 points for all 6 items delivered before 05/07/2020 (Sunday) by 23:59 +* no bonus points for delivering only some of the tasks before 05.07 +* 6 points for group work for each person in the group. + +___ + +## Task 1 + +Write a class `Store` that will allow you to make purchases. Use the enum and functions below. + +```cpp +enum class Response {done, lack_of_money, lack_of_cargo, lack_of_space}; + +Response buy(Cargo* cargo, size_t amount, Player* player); +Response sell(Cargo* cargo, size_t amount, Player* player); +``` + +___ + +## Exercise 2 + +In classes `Alcohol`, `Fruit`, `Item` add the missing methods and their implementations. + +```cpp +// override from Cargo +size_t getPrice() const override; +std::string getName() const override { return name_; } +size_t getAmount() const override { return amount_; } +size_t getBasePrice() const override { return base_price_; } +Cargo& operator+=(size_t amount) override; +Cargo& operator-=(size_t amount) override; +bool operator==(Cargo& cargo) const override; +``` + +___ + +## Exercise 3 + +Add to the class `Ship`, `Cargo` and `Store` method `nextDay()` + +* Class `Ship`: The method should subtract 1 coin for each crew member. +* Class `Cargo`: The method should spoil the goods. +* Class `Store`: The method should change the quantity of goods in stores. + +___ + +## Task 4 (for the ambitious) + +Try to write a class `Time` which will be responsible for time management in the game. + +This class should inform other classes, such as `Cargo`, `Ship`, `Store` about the expiry of each day. + +Read about [`Observer`](https://refactoring.guru/design-patterns/observer) design pattern. + +___ + +## Task 5 (for the ambitious) + +Write a friend operator that writes out to stream + +```cpp +friend std::ostream& operator<<(std::ostream& out, const Store& store); +``` + +It should write out the goods that are in a given store in an accessible way. + +___ + +## Task 6 (for the ambitious) + +Write a class `Game` that will manage the entire game. + +Add to it public method `startGame()`. + +Finally, the main file should look like this: + +```cpp +#include "Game.hpp" + +constexpr size_t start_money = 1'000; +constexpr size_t game_days = 100; +constexpr size_t final_goal = 2'000; + +int main() { + Game game(start_money, game_days, final_goal); + game.startGame(); + + return 0; +} +``` diff --git a/module2/presentation_homework.md b/module3/03_homework.pl.md similarity index 100% rename from module2/presentation_homework.md rename to module3/03_homework.pl.md diff --git a/module3/index.en.html b/module3/index.en.html new file mode 100644 index 000000000..97ca4ce35 --- /dev/null +++ b/module3/index.en.html @@ -0,0 +1,146 @@ + + + + + + + Object Oriented Programming - Coders School + + + + + + + + + + + + + + + +
+
+
+
+ +

OOP #3

+

Object-Oriented Programming #3

+ + Coders School + +

Mateusz Adamski

+

Łukasz Ziobroń

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+ +

Coders School

+ Coders School + +
+
+
+ + + + + + diff --git a/module3/index.html b/module3/index.pl.html similarity index 90% rename from module3/index.html rename to module3/index.pl.html index 7d4bf0fdd..508300689 100644 --- a/module3/index.html +++ b/module3/index.pl.html @@ -4,7 +4,7 @@ - Object Oriented Programming - Coders School + Programowanie Obiektowe - Coders School @@ -32,7 +32,7 @@

OOP #3

-

Object-Oriented Programming #3

+

Programowanie Obiektowe #3

Coders School @@ -62,9 +62,7 @@

Łukasz Ziobroń

## Zadania - Repo GH `coders-school/object-oriented-programming` - - [https://github.com/coders-school/object-oriented-programming/tree/master/module2](https://github.com/coders-school/object-oriented-programming/tree/master/module2) + [Repo GH `coders-school/object-oriented-programming`](https://github.com/coders-school/object-oriented-programming/tree/master/module2)
@@ -98,19 +96,19 @@

Łukasz Ziobroń

You can change the port by using npm start -- --port=8001. --> -
-
-
-
diff --git a/module4/pillars.md b/module4/00_pillars.en.md similarity index 100% rename from module4/pillars.md rename to module4/00_pillars.en.md diff --git a/module4/00_pillars.pl.md b/module4/00_pillars.pl.md new file mode 100644 index 000000000..379c1d34c --- /dev/null +++ b/module4/00_pillars.pl.md @@ -0,0 +1,12 @@ + + +# Cztery filary obiektowości + +___ + +## Cztery filary obiektowości + +* Abstrakcja +* Enkapsulacja +* Dziedziczenie +* Polimorfizm diff --git a/module4/abstraction.md b/module4/01_abstraction.en.md similarity index 100% rename from module4/abstraction.md rename to module4/01_abstraction.en.md diff --git a/module4/01_abstraction.pl.md b/module4/01_abstraction.pl.md new file mode 100644 index 000000000..24b99b697 --- /dev/null +++ b/module4/01_abstraction.pl.md @@ -0,0 +1,42 @@ + + +# Abstrakcja + +___ + +## Abstrakcja + +* Interfejs + * Publiczna część klasy + * Metody klasy + * Funkcje niebędące składowymi klasy + * Typy klasy + * Pola klasy + * Parametry szablonu + * Specjalizacje + * Przykład: std::vector na cppreference.com + * Część prywatna (implementacja) jest nieznana +* Projektowanie zorientowane obiektowo (OOD - Object Oriented Design) + +> Make interfaces easy to use correctly and hard to use incorrectly +> +> \ - \ - Scott Meyers, [Efektywne C ++](https://blog.ycshao.com/2012/11/23/effective-c-item-18-make-interfaces-easy-to-use-correctly-and-hard-to-use-incorrectly/) + + +___ + +## Zły przykład interfejsu + +```c++ +// A date class which is easy to use but also easy to use wrong. +class Date { + public: + Date(int month, int day, int year); + ... +}; + +// Both are ok, but some european programmer may use it wrong, +// because european time format is dd/mm/yyyy instead of mm/dd/yyyy. +Date d(3, 4, 2000); +Date d(4, 3, 2000); +``` diff --git a/module4/encapsulation.md b/module4/02_encapsulation.en.md similarity index 100% rename from module4/encapsulation.md rename to module4/02_encapsulation.en.md diff --git a/module4/02_encapsulation.pl.md b/module4/02_encapsulation.pl.md new file mode 100644 index 000000000..ae4f27533 --- /dev/null +++ b/module4/02_encapsulation.pl.md @@ -0,0 +1,14 @@ + + +# Enkapsulacja + +___ + +## Enkapsulacja + +* Specyfikatory dostępu + * public - struct domyślna + * protected + * private - class domyślna +* Settery i gettery +* Nienazwane przestrzenie nazw diff --git a/module4/inheritance.md b/module4/03_inheritance.en.md similarity index 100% rename from module4/inheritance.md rename to module4/03_inheritance.en.md diff --git a/module4/03_inheritance.pl.md b/module4/03_inheritance.pl.md new file mode 100644 index 000000000..9894df0f6 --- /dev/null +++ b/module4/03_inheritance.pl.md @@ -0,0 +1,27 @@ + + +# Dziedziczenie + +___ + +## Dziedziczenie + +* Porządek wywoływania konstruktorów i destruktorów + * Konstruktory - najpierw klasa bazowa, potem pochodna + * ideone.com +* Problem diamentowy + * dziedziczenie wirtualne +* dziedziczenie class od struct jest ... + * private +* dziedziczenie struct od class jest ... + * public + +___ + +## Modyfikatory dostępu do dziedziczenia + +| | public | protected | private | +| : ------------------------: | : ------------------------------------------------- ------: | : ------------------------------------------------- ------: | : ------------------------------------------------- ----: | +| **public** | publiczny | chroniony | prywatny | +| **protected** | chroniony | chroniony | prywatny | +| **private** | prywatny | prywatny | prywatny | diff --git a/module4/polymorphism.md b/module4/04_polymorphism.en.md similarity index 100% rename from module4/polymorphism.md rename to module4/04_polymorphism.en.md diff --git a/module4/04_polymorphism.pl.md b/module4/04_polymorphism.pl.md new file mode 100644 index 000000000..4bcdc3886 --- /dev/null +++ b/module4/04_polymorphism.pl.md @@ -0,0 +1,15 @@ + + +# Polimorfizm + +___ + +## Polimorfizm + +* Funkcje wirtualne +* funkcje czysto wirtualne (=0) +* Klasy abstrakcyjne + * mają co najmniej jedną funkcję czysto wirtualną +* vtable i vptr + * implementacja polimorfizmu + * Konstruktor klasy pochodnej przesłania rekordy klasy bazowej w vtable diff --git a/module4/exercise_cars.md b/module4/05_exercise_cars.en.md similarity index 100% rename from module4/exercise_cars.md rename to module4/05_exercise_cars.en.md diff --git a/module4/05_exercise_cars.pl.md b/module4/05_exercise_cars.pl.md new file mode 100644 index 000000000..69ef42ab1 --- /dev/null +++ b/module4/05_exercise_cars.pl.md @@ -0,0 +1,19 @@ + + +# Zadanie + +___ + +## Samochody + +1. Zaprojektuj odpowiednią abstrakcję (interfejsy) +2. Zastosuj dziedziczenie +3. Napraw hermetyzację +4. Użyj polimorfizmu, aby przedstawić każdy typ samochodu za pomocą jednego wskaźnika +5. Napraw problem diamentowy +6. Napraw potencjalne wycieki pamięci +7. Pomyśl o sposobie przechowywania silników w samochodach. Czy powinny być przechowywane przez wartość, referencję czy wskaźnik (jaki rodzaj wskaźnika)? +8. Czy ten kod można przetestować? + +### [Wyświetl zadanie w repozytorium](https://github.com/coders-school/Cars.git) + diff --git a/module4/post_work.md b/module4/06_post_work.en.md similarity index 100% rename from module4/post_work.md rename to module4/06_post_work.en.md diff --git a/module4/06_post_work.pl.md b/module4/06_post_work.pl.md new file mode 100644 index 000000000..d181940cc --- /dev/null +++ b/module4/06_post_work.pl.md @@ -0,0 +1,17 @@ + + +# Post-work + +___ + +## Post-work + +Możesz pracować w grupach lub indywidualnie. Zrób forka repozytorium Cars i Pull Requesta po zakończeniu. + +1. (4 XP) Utwórz wyjątek InvalidGear. Należy go rzucić, gdy ktoś próbuje np. zmienić bieg z 5 na wsteczny. Powinien dziedziczyć z jednego z wyjątków STL +2. (2 XP za każdą poprawkę) Napraw interfejsy, aby były łatwe w użyciu, poprawne i trudne w użyciu nieprawidłowo (np. accelerate(-999)) +3. (10 XP - opcjonalnie) Napisz odpowiednie testy jednostkowe do tego kodu +4. Przeczytaj jeden z poniższych artykułów. Przyda się na następną lekcję + + * SOLID czyli dobre praktyki w programowaniu obiektowym (po polsku) + * S.O.L.I.D: The First 5 Principles of Object Oriented Design (po angielsku) diff --git a/module4/index.html b/module4/index.en.html similarity index 88% rename from module4/index.html rename to module4/index.en.html index 2b02a08c5..f24101b92 100644 --- a/module4/index.html +++ b/module4/index.en.html @@ -69,25 +69,25 @@

Łukasz Ziobroń

You can change the port by using npm start -- --port=8001. --> -
-
-
-
-
-
-
diff --git a/module4/index.pl.html b/module4/index.pl.html new file mode 100644 index 000000000..369f60c6f --- /dev/null +++ b/module4/index.pl.html @@ -0,0 +1,125 @@ + + + + + + + Programowanie Obiektowe - Coders School + + + + + + + + + + + + + + + + +
+
+
+
+ +

OOP #4

+

Programowanie Obiektowe #4

+ + Coders School + +

Łukasz Ziobroń

+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +

Coders School

+ Coders School + +
+
+ +
+ + + + + +