NemProgrammering.dk logo

OOP Nedarvning

Lær Python programmering » OOP Nedarvning # 14
Inkluderet:
Livstidsadgang
27 videolektioner
7 timers undervisning
Stil spørgsmål
Kursusbevis

Information om denne video

Underviser: Simon Rotendahl   Video: 18:05   Lektion nr. 14 af 27

Hvad hvis jeg vil have en klasse til hver genre?

Lad os forestille os vores Film klasse eksempel, fra en tidligere videobeskrivelse. Vores Film klasse bliver lige pludselig lidt for generel. Vi er interesserede i at dele den mere op. Det kan vi gøre med nedarvning. Med nedarvning kan vi lave underklasser, til en klasse. Vi kan f.eks lave en underklasse, af Film, der hedder ‘Gyser’, den har alle variabler og metoder fra Film klassen (udgivelsesår, hovedrolle osv.) men vi kan nu tilføje flere, f.eks antal dødsfald, antal jumpscares, altså ting der mest kun giver mening i en gyserfilm, vi har derfor ikke lyst til at det skal være variabler i Film klassen, fordi i Pixars Op, så giver dødsfald ikke mening at tælle. Det er derfor det er smart at lave underklasser!

Dette er sidste video om OOP, det kræver dog utrolig meget erfaring, før man bliver god til det, så øv dig så meget du kan. Næste video handler om filer!

Spørgsmål og kommentarer

Kun medlemmer med adgang til dette kursus kan stille spørgsmål og kommentere. Bliv medlem her!

  • Louise R. siger:

    Hej Simon

    Har lidt problmer med kommandoen, hvor man får hunden til at spille med bold.

    Har sagt følgende:

    def play(self, ting):
    print(“I play catch wit a”,ting)

    men når jeg siger

    Fido.play(“ball”)

    Siger den at play ikke eksistere. Hvad har jeg gjort forkert??

    1. Louise R. siger:

      I terminalen siger det:

      Traceback (most recent call last):
      File “class.py”, line 38, in
      Fido.play(“ball”)
      ^^^^^^^^^
      AttributeError: ‘Dog’ object has no attribute ‘play’

      1. Simon R. siger:

        Hej Louise,

        Den mest oplagte fejl vil være at play metoden ikke er indrykket korrekt, så det bør se sådan her ud
        class Dog(Animal):
        ...
        def play(self, ting):
        print(“I play catch wit a”,ting)

        det jeg tænker der kan være sket for dig er at du har
        class Dog(Animal):
        ...
        def play(self, ting):
        print(“I play catch wit a”,ting)

        Hvis det ikke er problemet, vil du så prøve at kopiere hele din kode og skrive den her, så kan jeg bedre se hvad problemet er :)

        Mvh.
        Simon

        1. Louise R. siger:

          Burde have placeringen på plads da den har opfanget play, men den vil ikke lave den til en funktion ved siden af Fido.
          Her er alt hvad jeg har lavet

          class Animal:
          “””En klasse for konceptet dyr”””
          alive = “Yes”
          numAni = 0

          def __init__(self, gender):
          self.gender = gender
          Animal.numAni = Animal.numAni + 1

          def speak(self):
          “””
          En metode for
          dyr til at sige noget
          “””
          print(“i am an animal”)

          class Dog(Animal):
          “””En klasse for arten hund”””
          numDog = 0

          def __init__(self, race, gender, owner):
          super().__init__(gender)
          self.race = race
          self.owner = owner
          self.present = (“I am a {0} and my race is {1} and my owner is called {2}”
          .format(__class__.__name__, self.race, self.owner))
          Dog.numDog += 1

          def speak(self):
          print(“Bark!!”)

          def play(self, ting):
          print(“I play catch wit a”,ting)

          Fido = Dog(“lab”, “female”, “Simon”)
          print(Fido.present)
          Fido.speak()
          Fido.play(“ball”)

          1. Louise R. siger:

            Har også lavet indrykkende korrekt

            1. Simon R. siger:

              Hmm det lyder mærkeligt, jeg kan ikke umiddelbart se nogen fejl, og jeg har prøvet at kopiere det ind i min egen, og der kør det fint. Jeg har lavet et link herunder til en online tekst behandler, hvor jeg har kopieret din kode ind, og der kan du prøve at køre den (der ser den ud til at virke), og så sammenligne med din egen og se om der er nogen forskelle, hvis ikke der er det, så må du sige til :)

              Mvh.
              Simon

  • Dennis J. siger:

    Hej Simon,

    Hvordan ved jeg, når jeg skriver super under klassen hund, at den så nedarver fra klassen dyr? Er det fordi klassen dyr står øverst?

    mvh

    Dennis

    1. Simon R. siger:

      Hej Dennis,

      Det er fordi vi skriver
      class Dog(Animal)
      Så alle steder vi skriver super kan du erstatte med Animal.

      Det er lidt forsimplet, for hvad nu man gerne vil nedarve fra mere end en klasse f.eks
      class Dog(Animal, Pet)
      Så man altså både vil nedarve fra Animal og Pet. Det kan man også uden problem og samme logik følge først bliver den ene klasses init funktion kørt og så den anden, så langt hen af vejen vil logikken holde. Det kan dog være at Animal og Pet har en konflikt mellem sig (hvis de f.eks har metoder med samme navne) hvad man så gør er lidt ude for hvad vi skal lære her på kurset det er ikke kompliceret rent kode mæssigt, men hvorfor tingene er som de er tager lidt tid at skulle lære :)

      Mvh.
      Simon

  • Arne Emil H. siger:

    Hej Simon, ligesom man kan referere til klassens navn Dog, kan man også referere til variablens eget navn? Så Misser.present også gav “and my name is >Misser<"

    Herudover, i tilfælde af eksemplet- hvorfor er vi interesseret i at have race isoleret hos hund og kat?, kunne det fx være fordi man ønsker at isolere racerne inde for hver enkelt dyr fx i tilfælde af at man ville slå op i listen af indkommende racer senere? Real life example kunne være et dyreinternat eller hvad ved jeg. Og i forlængelse af det- kan vi allerede nu skrive en kode således vi får output der giver os alle de raceinputs vi har fået? Nu er der i eksemplet kun defineret 1 hund men hvis vi havde defineret fx 3 forskellige racer? jeg tænker noget i retning af print(dog.race) -som dog ikke ville virke :D

    1. Simon R. siger:

      Hej Arne Emil

      Igen undskyld for det lidt sene svar.

      Godt spørgsmål mht. variablens egent navn, det kan man ikke så vidt jeg ved. Hvis du ville gemme navnet så ville du tilføje det i init funktionen, altså
      class Animal:
      def __init__(self,species,race,gender,name):
      self.species = species
      self.race = race
      self.gender = gender
      self.name = name
      og så have at
      Fido = Animal(“hund”,”mops”,”female”,”Fido”)

      Helt grundlæggende så er nedarvningen noget man gør for at skrive mindre kode og spare tid, så det kan være lidt svært at se her da eksemplet er lidt mindre, forestil at du skulle kode en hjemmeside for en Zoo, hvert dyr skulle have en underside for sig selv, i stedet for at du skal kode hver underside fra bunden af, så kan du lave nedarvning, så du starter med de karakteristika alle dyr har, f.eks hvor i verdenen kommer dyret fra, men ved f.eks rovdyr som løver, tigere osv. så vil du måske gerne vide hvor hurtigt de kan løbe, så i stedet for at kode deres side helt fra bunden, så nedarver du fra den overordnet klasse, og så tilføjer du f.eks topfart, ved fugle nedarver du og tilføjer måske vingespænd.
      Så kort sagt, nedarvning er en form for ‘copy-paste’, som vi programmøre gør, da det spare os fra at skrive mere kode. Nedarvning er aldrig en nødvendighed, der er intet problem du kun kan løse hvis du har nedarvning, det er udelukkende noget vi gør for struktur, og spare os for kedeligt arbejde :)

      Mht. det med de forskellige racer, så kan man fint det, det skal bare kodes, jeg har lavet et lille eksempel du kan se på, jeg har ikke kommenteret det, tænker at det måske er mere lærerigt hvis du selv kigger på det (du skal dog bare spørge hvis det ikke giver mening efter noget tid).

      Eksempel – https://pastebin.com/fKj4TnhF

      Mvh.
      Simon

  • Thomas Bach J. siger:

    Hej og tak for rigtig fin video om nedarvning.

    Jeg har et praktisk spørgsmål omkring store og små bogstaver, jeg tænker, at det hører hjemme et andet sted, men nu så jeg det lige her. I self.present tager den ordet fra (under)klassens navn (hvis jeg har forstået det korrekt), f.eks. ‘Dog’ i denne video. Det bliver til “I am a Dog and……” Er det (bogstaver og formattering) noget, der rettet sig til senere, når det udmønter sig i brugergrænsefladen. Jeg har set din tidligere forklaring på når vi laver navne på nye klasser m.m, og det er jeg helt med på og giver god mening.

    1. Simon R. siger:

      Tak for de pæne ord :)

      Du har helt ret i at den tager navnet fra klassen med Dog eksemplet. Jeg er dog ikke helt sikker på hvad du spørg om mht. retter sig til senere? Kan du uddybe lidt.

      Jeg kan kort nævne at der er funktioner i python som vil ændre på store og små bogstaver f.eks kan du skrive
      “SiMoN”.lower() hvilket vil give “simon”
      og
      “SiMoN”.upper() hvilket vil give “SIMON”
      ved ikke om det har noget at gøre med det du spurgte om, men ville lige nævne det hvis det var :)

      Mvh.
      Simon

      1. Thomas Bach J. siger:

        Hej igen

        Tak for svar. Det jeg mente med at “det retter sig til senere” var, at jeg forestiller mig, at når man er færdig med at kode, så er der efterfølgende en proces i hvilken man kigger på, hvordan det præsenterer sig for slutbrugeren af programmet. Måske ønsker man, at noget af teksten står i BOLD, andet tekst måske med andre formatteringer. Gøres det også i Python eller kan gøres det typisk i et andet program? Mvh Thomas

        1. Simon R. siger:

          Det kommer meget an på hvad ens program gør, men man kan godt gøre det i Python, og alt efter hvad man laver kan de være en fin ide. I excel videoerne her i kurset gør vi f.eks tekst bold i en cele, med Python.

          Så det er lidt svært at svare konkret på, da det afhænger af situationen, men for at printe fed i terminalen kan du bruge linjen her

          print (‘\033[1m’ + ‘Dine fede tekst her’ + ‘\033[0m’)

          Du har her at ‘\033[1m’ starter bold tekst og at ‘\033[0m’ slutter bold tekst. Hvordan det helt præcis virker er en lidt længere snak, det har noget med ASCII at gøre, så hvis du har hørt det før, og gerne vil vide mere om hvordan det virker, så må du sige til, så prøver jeg at uddybe og finde nogle resourcer hvor du kan se mere :)

          Jeg håber det hjalp
          Mvh.
          Simon