Przejdź do zawartości

Koncepcje programowania/OOP

Z Wikibooks, biblioteki wolnych podręczników.

Koncepcje programowania obiektowego[edytuj]

Programowanie obiektowe (OOP) to sposób pisania programów komputerowych, które ułatwiają je zrozumienie i ponowne wykorzystanie. W OOP programiści myślą o swoim kodzie pod względem obiektów, które są jak małe maszyny, które robią rzeczy.

Wyobraź sobie, że masz zabawkowy samochód. Ma kształt, kolor i rozmiar i może poruszać się do przodu, do tyłu, lewej i prawej. Ma również kierowcę, który może kontrolować samochód i sprawić, że się porusza. Jest to podobne do działania obiektu w OOP.

W OOP obiekty mają dwie ważne części: atrybuty i metody. Atrybuty są cechami obiektu, takiego jak jego kolor, kształt lub rozmiar. Metody to działania, które obiekt może wykonywać, takie jak poruszanie lub zmiana kształtu.

Wróćmy do naszego przykładu samochodu zabawkowego. Atrybuty samochodu mogą być jego kolor, rozmiar i kształt. Metody samochodu mogą się poruszać do przodu, do tyłu, w lewo i w prawo. Metody kierowcy mogą być sterowanie samochodem i naciskanie pedału gazu.

Kiedy piszemy kod za pomocą OOP, tworzymy klasy, które określają, jak powinien wyglądać obiekt i co może zrobić. Zajęcia są jak szablony obiektów. Używamy klas do tworzenia instancji obiektów, które są jak kopie szablonu, które możemy użyć w naszym programie.

W naszym przykładzie samochodu zabawka klasa określiłaby, jak powinien wyglądać samochód i co może zrobić. Moglibyśmy użyć klasy do tworzenia wielu wystąpień obiektu CAR, każdy z własnymi unikalnymi atrybutami i metodami.

OOP ułatwia programowanie, ponieważ pozwala nam ponownie wykorzystać kod. Zamiast pisać ten sam kod w kółko dla różnych części naszego programu, możemy tworzyć klasy, które definiują potrzebne obiekty i używać tych obiektów w całym naszym kodzie. To sprawia, że nasz kod jest łatwiejszy do odczytania, zrozumienia i utrzymania.

Podsumowując, OOP jest sposobem pisania kodu, który obejmuje myślenie o obiektach z atrybutami i metodami. Używamy klas do zdefiniowania tych obiektów i tworzenia ich wystąpień w całym naszym kodzie. OOP sprawia, że programowanie jest łatwiejsze i bardziej wydajne, umożliwiając nam ponowne wykorzystanie kodu i zwiększenie zorganizowania naszych programów.

Obiekty[edytuj]

obiekt jest jak specjalna rzecz, która może robić różne rzeczy i przechowywać informacje.

Na przykład wyobraź sobie, że masz samochodzik. Samochodzik jest obiektem i zawiera pewne informacje, takie jak kolor, rozmiar i prędkość. Może też wykonywać różne czynności, na przykład poruszać się do przodu, skręcać w lewo lub w prawo i wydawać dźwięk.

W programowaniu obiekty są podobne. Mają właściwości (informacje) i metody (rzeczy, które mogą zrobić). Na przykład możesz mieć obiekt reprezentujący osobę. Ten obiekt osoby może mieć takie właściwości, jak imię i nazwisko, wiek i wzrost. Może również mieć metody, takie jak chodzenie, bieganie, jedzenie i spanie.

Ogólnie rzecz biorąc, obiekty w OOP umożliwiają programistom tworzenie złożonych systemów poprzez dzielenie ich na mniejsze, łatwiejsze w zarządzaniu części, które mogą ze sobą współdziałać.

Klasy[edytuj]

klasa jest jak plan lub przepis na tworzenie obiektów.

Pomyśl o tym jak o pieczeniu ciasteczek. Masz przepis, który mówi ci, jakich składników potrzebujesz i jak je połączyć. Przepis jest jak klasa, a ciasteczka, które robisz, są jak przedmioty.

W programowaniu klasa jest podobna. Definiuje właściwości i metody, które będą miały obiekty tej klasy. Na przykład możesz mieć klasę reprezentującą samochód. Klasa określałaby właściwości samochodu, takie jak jego kolor, marka, model i rok. Określiłoby również metody, które samochód może wykonać, takie jak jazda, hamowanie i przyspieszanie.

Kiedy tworzysz obiekt z klasy, przypomina to pieczenie ciastka z przepisu. Używasz planu (klasy) do utworzenia obiektu (cookie), a obiekt ma wszystkie właściwości i metody, które zostały zdefiniowane w klasie.

Ogólnie rzecz biorąc, klasy w OOP umożliwiają programistom tworzenie wielu podobnych obiektów o tych samych właściwościach i metodach, co ułatwia zarządzanie kodem i organizowanie go.

Abstrakcja[edytuj]

abstrakcja jest jak ukrywanie skomplikowanych części czegoś i pokazywanie tylko tych części, które są ważne lub niezbędne.

Na przykład wyobraź sobie, że masz samochodzik z pilotem. Na pilocie znajdują się przyciski, które pozwalają na wprawienie autka w ruch do przodu, skręt w lewo lub w prawo oraz wydanie dźwięku. Nie musisz wiedzieć, jak samochód faktycznie się porusza ani jak działa pilot. Musisz tylko wiedzieć, które przyciski nacisnąć, aby samochód zrobił to, co chcesz.

W programowaniu abstrakcja jest podobna. Pozwala skupić się na ważnych częściach obiektu lub systemu i zignorować szczegóły, które nie są ważne. Na przykład, jeśli masz klasę, która reprezentuje samochód, nie musisz znać wszystkich szczegółów dotyczących działania silnika lub sposobu zmiany biegów przez skrzynię biegów. Musisz tylko wiedzieć, jak korzystać z dostępnych metod prowadzenia samochodu.

Abstrakcja ułatwia zarządzanie i pracę ze złożonymi systemami, upraszczając je i ukrywając niepotrzebne szczegóły. Pozwala skupić się na tym, co ważne i zignorować resztę, co ułatwia zrozumienie i utrzymanie kodu.

Enkapsulacja[edytuj]

enkapsulacja jest jak utrzymywanie rzeczy w bezpiecznym i zorganizowanym pojemniku lub pudełku.

Na przykład wyobraź sobie, że masz pudełko na zabawki, które ma różne przegródki na różne rodzaje zabawek. W jednej komorze umieszczasz swoje figurki, w drugiej samochodziki, a w trzeciej pluszaki. W ten sposób wszystkie zabawki są uporządkowane i łatwe do znalezienia.

W programowaniu enkapsulacja jest podobna. Oznacza to utrzymywanie właściwości i metod obiektu lub klasy w ukryciu i ochronie przed dostępem z zewnątrz. Zwykle odbywa się to za pomocą modyfikatorów dostępu, takich jak private lub protected.

Hermetyzacja zapewnia dostęp do właściwości i metod obiektu oraz ich modyfikację wyłącznie w bezpieczny i kontrolowany sposób. Pomaga to również zapobiegać błędom i usterkom w kodzie, ponieważ właściwości i metody są chronione przed ingerencją z zewnątrz.

Ogólnie rzecz biorąc, enkapsulacja jest ważną koncepcją w OOP, ponieważ pomaga utrzymać porządek, bezpieczeństwo i łatwość zarządzania kodem

Dziedziczenie[edytuj]

dziedziczenie jest jak przekazywanie cech z rodziców na dzieci.

Na przykład wyobraź sobie, że masz rodzinę składającą się z matki, ojca i dziecka. Matka ma brązowe oczy, ojciec ma kręcone włosy, a dziecko dziedziczy obie cechy i ma brązowe oczy i kręcone włosy.

W programowaniu dziedziczenie jest podobne. Pozwala utworzyć nową klasę opartą na istniejącej klasie i odziedziczyć wszystkie właściwości i metody klasy nadrzędnej. Ta nowa klasa jest nazywana podklasą, a oryginalna klasa nazywana jest nadklasą.

Na przykład wyobraź sobie, że masz nadklasę reprezentującą pojazd. Pojazd ma takie właściwości, jak prędkość, waga i oszczędność paliwa, a także metody, takie jak jazda, hamowanie i przyspieszanie. Możesz utworzyć podklasę reprezentującą samochód i odziedziczyć wszystkie właściwości i metody nadklasy pojazdu. Podklasa samochodu miałaby wszystkie te same właściwości i metody, co pojazd, ale mogłaby mieć również dodatkowe właściwości i metody, które są specyficzne dla samochodów, takie jak liczba drzwi lub rodzaj skrzyni biegów.

Dziedziczenie umożliwia tworzenie nowych klas opartych na istniejących klasach, co ułatwia zarządzanie i organizowanie kodu. Pozwala również na ponowne użycie kodu, który już napisałeś, co może zaoszczędzić czas i wysiłek.

Polimorfizm[edytuj]

polimorfizm przypomina możliwość przybierania różnych form.

Na przykład wyobraź sobie, że masz zabawkę, która może przekształcić się w samochód, robota lub samolot. Może zmieniać swój kształt i wygląd w zależności od tego, co chcesz.

W programowaniu polimorfizm jest podobny. Pozwala używać tej samej metody lub funkcji z różnymi obiektami i uzyskiwać różne wyniki w zależności od typu używanego obiektu.

Na przykład wyobraź sobie, że masz nadklasę o nazwie Kształt i dwie podklasy o nazwie Koło i Kwadrat. Obie podklasy Okrąg i Kwadrat dziedziczą z nadklasy Kształt i obie mają metodę o nazwie obliczObszar. Metoda calcalArea w podklasie Circle służy do obliczania pola koła, podczas gdy metoda calcArea w podklasie Square oblicza pole kwadratu.

Kiedy wywołasz metodę CalcArea na obiekcie Circle, użyje on metody z podklasy Circle i obliczy pole koła. Gdy wywołasz tę samą metodę na obiekcie Square, użyje on metody z podklasy Square i obliczy pole kwadratu.

To jest polimorfizm w działaniu - ta sama metoda jest używana z różnymi obiektami i może przybierać różne formy i dawać różne wyniki w zależności od typu używanego obiektu.

Ogólnie rzecz biorąc, polimorfizm jest ważną koncepcją w OOP, ponieważ umożliwia tworzenie elastycznego i elastycznego kodu, który może pracować z różnymi obiektami i typami.

Tworzenie i używanie klas[edytuj]

Aby utworzyć klasę w większości języków programowania, zwykle używa się słowa kluczowego class, po którym następuje nazwa klasy i zestaw nawiasów klamrowych obejmujących właściwości i metody klasy. Na przykład w Pythonie możesz utworzyć klasę reprezentującą samochód w następujący sposób:

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def get_make(self):
        return self.make

    def get_model(self):
        return self.model

    def get_year(self):
        return self.year

W tym przykładzie zdefiniowaliśmy klasę o nazwie Car, która ma trzy właściwości: markę, model i rok. Zdefiniowaliśmy również trzy metody (lub funkcje), które umożliwiają nam dostęp do tych właściwości.

Korzystanie z klasy Po utworzeniu klasy możesz jej użyć do tworzenia obiektów w swoim programie. Aby utworzyć obiekt z klasy, zwykle używasz nazwy klasy, po której następuje nawias. Na przykład, aby utworzyć instancję klasy Car, którą zdefiniowaliśmy wcześniej, moglibyśmy napisać:

my_car = Car("Toyota", "Corolla", 2020)

Spowoduje to utworzenie nowego obiektu typu Car i przypisanie go do zmiennej my_car. Przekazaliśmy również trzy argumenty do konstruktora Car (metoda init), który ustawia markę, model i rok obiektu.

Gdy masz obiekt klasy, możesz użyć jego właściwości i metod, używając notacji kropkowej. Na przykład, aby uzyskać markę my_car, możemy napisać:

make = my_car.get_make()

Spowodowałoby to wywołanie metody get_make na obiekcie my_car i zwrócenie jej właściwości make.

Wniosek Tworzenie i używanie klas to podstawowa koncepcja OOP, która umożliwia programistom tworzenie kodu wielokrotnego użytku i modułowego. Definiując klasy reprezentujące obiekty w swoim programie, możesz utworzyć wiele instancji tych obiektów i używać ich do wykonywania różnych zadań. Postępując zgodnie z najlepszymi praktykami projektowania i implementacji klas, możesz tworzyć kod, który jest łatwiejszy w utrzymaniu, rozszerzalny i skalowalny.

Przykład w języku JavaScript:

// Define a class called "Person"
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
  }
}

// Create a new instance of the Person class
const john = new Person("John", 30);

// Call the "greet" method on the john object
john.greet();

Przykład w języku elisp:

;; Define a class called "Person"
(defclass person ()
  ((name :initarg :name :type string)
   (age :initarg :age :type integer)))

;; Define a method for the "Person" class
(defmethod greet ((p person))
  (message "Hello, my name is %s and I'm %d years old."
           (oref p name) (oref p age)))

;; Create a new instance of the "Person" class
(setq john (make-instance 'person :name "John" :age 30))

;; Call the "greet" method on the "john" object
(greet john)

Praktyka[edytuj]

Python[edytuj]

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

    def read_odometer(self):
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")

    def increment_odometer(self, miles):
        self.odometer_reading += miles

# Create an instance of the Car class
my_car = Car('audi', 'a4', 2019)

# Print the car's make, model, and year
print(my_car.get_descriptive_name())

# Read the odometer of the car
my_car.read_odometer()

# Update the odometer reading
my_car.update_odometer(5000)

# Increment the odometer reading
my_car.increment_odometer(100)

# Read the odometer again to see the changes
my_car.read_odometer()

JavaScript[edytuj]

// Define a class called "Person"
class Person {
  // Constructor function to set initial values for the object
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  // A method to print out the name and age of the person
  printInfo() {
    console.log(`My name is ${this.name} and I am ${this.age} years old.`);
  }
}

// Create a new object from the Person class
const person1 = new Person("John", 30);

// Call the printInfo method to display the object's properties
person1.printInfo(); // Output: "My name is John and I am 30 years old."

elisp[edytuj]

(defclass car ()
  ((make :accessor car-make)
   (model :accessor car-model)
   (year :accessor car-year)
   (odometer-reading :accessor car-odometer-reading)))

(defmethod initialize-instance :after ((car car) &key)
  (setf (car-odometer-reading car) 0))

(defmethod get-descriptive-name ((car car))
  (format "%d %s %s" (car-year car) (car-make car) (car-model car)))

(defmethod read-odometer ((car car))
  (message "This car has %d miles on it." (car-odometer-reading car)))

(defmethod update-odometer ((car car) mileage)
  (if (>= mileage (car-odometer-reading car))
      (setf (car-odometer-reading car) mileage)
    (message "You can't roll back an odometer!")))

(defmethod increment-odometer ((car car) miles)
  (incf (car-odometer-reading car) miles))

;; Create an instance of the Car class
(defvar my-car (make-instance 'car :make "Audi" :model "A4" :year 2019))

;; Print the car's make, model, and year
(message "%s" (get-descriptive-name my-car))

;; Read the odometer of the car
(read-odometer my-car)

;; Update the odometer reading
(update-odometer my-car 5000)

;; Increment the odometer reading
(increment-odometer my-car 100)

;; Read the odometer again to see the changes
(read-odometer my-car)