Programmering nivå 2

Kap 3.7 – Objektorienterat projekt

Planera, strukturera och bygg ett projekt med flera samverkande klasser.

Mål med lektionen

När du har arbetat klart med denna lektion ska du:

  • Självständigt kunna planera och strukturera ett objektorienterat program.
  • Använda flera samverkande klasser med inkapsling, arv och metodanrop.
  • Skapa kod som är organiserad, dokumenterad och återanvändbar.

Så här lär du dig bäst

Börja med att rita ett klassdiagram över ditt projekt. Fundera över vilka objekt som behövs, hur de ska kommunicera och vilka metoder varje klass ska ha. Bygg först en enkel version och testa varje del för sig innan du sätter ihop helheten. Kommentera din kod tydligt.

Centrala begrepp

  • Klassstruktur: hur du planerar upp programmet i olika klasser.
  • Objektsamverkan: hur objekten kommunicerar och använder varandra.
  • Modularisering: att dela upp programmet i separata, återanvändbara delar.
  • Projektmappstruktur: hur du organiserar filer och moduler i Python.

Uppgift: planera och skapa ett OOP-baserat projekt

Du ska skapa ett mindre Pythonprojekt där flera klasser samarbetar. Projektet ska ha en tydlig struktur, ett klassdiagram och kod som visar att du förstår objektorienterad programmering.

Förslag på projektidéer

  1. Bibliotekssystem: hantera böcker, låntagare och utlåningar. Klasser kan vara Book, Member och Library.
  2. RPG-strid: låt en spelare slåss mot fiender i turordning. Klasser kan vara Character, Player, Enemy och Item.
  3. Receptplanerare: låt användaren lägga till recept, söka och skapa inköpslistor. Klasser kan vara Recipe, Ingredient och MealPlanner.

Steg-för-steg-struktur

  1. Designa: skapa ett UML-diagram med minst tre klasser. Beskriv attribut, metoder, relationer, arv och inkapsling.
  2. Bygg grundstruktur: skapa en huvudfil, till exempel main.py, och separata filer per klass.
  3. Utöka med arv och logik: lägg till subklasser där det passar och använd super() när du bygger vidare på en basklass.
  4. Testa objekt och metodanrop: skapa instanser och prova att anropa metoder i ett konkret scenario.
  5. Dokumentera: kommentera varje klass och metod. Lägg till en README-fil där du förklarar programmets syfte och hur det körs.

Lösningsförslag: bibliotekssystem

Det här är ett exempel på hur ett projekt kan struktureras. Använd det som stöd, men skapa gärna en egen variant.

classDiagram
    Library -- Book : contains
    Library -- Member : registers
    Member -- Book : borrows

    class Book {
        -string title
        -string author
        -bool available
        +borrow() bool
        +return_book() void
        +__str__() string
    }

    class Member {
        -string name
        -list borrowed_books
        +borrow_book(book) void
        +return_book(book) void
        +list_books() void
    }

    class Library {
        -list books
        -list members
        +add_book(title, author) void
        +register_member(name) void
        +find_book(title) Book
        +find_member(name) Member
        +list_books() void
    }

book.py

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author
        self.available = True

    def borrow(self):
        if self.available:
            self.available = False
            return True
        return False

    def return_book(self):
        self.available = True

    def __str__(self):
        status = "Tillgänglig" if self.available else "Utlånad"
        return f"{self.title} av {self.author} - {status}"

member.py

class Member:
    def __init__(self, name):
        self.name = name
        self.borrowed_books = []

    def borrow_book(self, book):
        if book.borrow():
            self.borrowed_books.append(book)
            print(f"{self.name} lånade {book.title}.")
        else:
            print(f"{book.title} är redan utlånad.")

    def return_book(self, book):
        if book in self.borrowed_books:
            book.return_book()
            self.borrowed_books.remove(book)
            print(f"{self.name} lämnade tillbaka {book.title}.")
        else:
            print(f"{self.name} har inte {book.title}.")

    def list_books(self):
        if not self.borrowed_books:
            print(f"{self.name} har inga böcker.")
        else:
            print(f"{self.name} har lånat:")
            for book in self.borrowed_books:
                print(f"- {book}")

library.py

from book import Book
from member import Member

class Library:
    def __init__(self):
        self.books = []
        self.members = []

    def add_book(self, title, author):
        book = Book(title, author)
        self.books.append(book)

    def register_member(self, name):
        member = Member(name)
        self.members.append(member)

    def find_book(self, title):
        for book in self.books:
            if book.title == title:
                return book
        return None

    def find_member(self, name):
        for member in self.members:
            if member.name == name:
                return member
        return None

    def list_books(self):
        print("Böcker i biblioteket:")
        for book in self.books:
            print(f"- {book}")

main.py

from library import Library

lib = Library()

lib.add_book("1984", "George Orwell")
lib.add_book("Sagan om ringen", "J.R.R. Tolkien")
lib.register_member("Ali")

book1 = lib.find_book("1984")
member = lib.find_member("Ali")

if book1 and member:
    member.borrow_book(book1)

member.list_books()
lib.list_books()

Alternativa projektstrukturer

RPG-strid

classDiagram
    Character <|-- Player
    Character <|-- Enemy
    Player -- Item : uses

    class Character
    Character : name
    Character : hp
    Character : attack
    Character : is_alive()
    Character : take_damage(amount)
    Character : deal_damage(target)

    class Player
    Player : inventory
    Player : use_item(item)

    class Enemy
    Enemy : name
    Enemy : hp

    class Item
    Item : name
    Item : effect
    Item : use(target)

Receptplanerare

classDiagram
    MealPlanner -- Recipe : stores
    Recipe -- Ingredient : contains

    class Ingredient {
        -string name
        -float amount
        -string unit
        +__str__() string
    }

    class Recipe {
        -string name
        -list ingredients
        +add_ingredient(name, amount, unit) void
        +list_ingredients() void
    }

    class MealPlanner {
        -list recipes
        +add_recipe(recipe) void
        +list_all_recipes() void
        +generate_shopping_list() void
    }

Öva: planera ditt eget projekt

  1. Välj ett av förslagen ovan eller kom på ett eget projekt.
  2. Rita upp ett klassdiagram.
  3. Lista attribut och metoder för varje klass.
  4. Skapa kod för minst tre samverkande klasser.
  5. Presentera din kodstruktur och vad varje del gör.

Sammanfattning

  • Ett objektorienterat projekt bygger på samspel mellan flera klasser.
  • Bra planering, till exempel via UML, gör det lättare att bygga upp strukturen.
  • Du använder inkapsling, arv och modularisering för att skapa en hållbar kodbas.
  • Testa varje klass för sig innan du sätter ihop hela programmet.

Tillbaka till Kapitel 3