Objekt orienteret

Nu kombinerer vi den sidste øvelse (funktioner og ‘key-value pairs’) i programmerings nærmeste abstraktion af virkeligheder; objekt orienteret programmering. Når man vil programmerer noget, skal man først analysere opgaven og dele op hvad man har at gøre med, og hvilke egenskaber det har og hvad det skal kunne. Og det må gerne ligge tæt på virkeligheder. Det ‘hvad‘ bliver et ‘objekt’, ligesom alting i den virkelige verden er et objekt, (fx en bil). Hvert objekt har nogle egenskaber (fx. mærke, model, farve) og nogle funktioner (fx køre forlands og baglands, dreje til højre og til venstre, dytte), og for nogle af disse funktioner er afhængig af bruger input (hvor meget gas man giver, hvor skarp man drejer).

En definition af sådan et objekt, kalder vi en klasse.

Jeg starter lige med et nemt eksempel for ikke at forskrække dig med den nye kode. Efterfølgende kommer et anelse mere udbredt eksempel, der gerne skal åbne øjne op for dig for at se hvordan man kan bruge det.

Python

# -*- coding: utf-8 -*-

class SimpelPerson(object):
    def __init__(self, fornavn, efternavn):
        self.fornavn = fornavn
        self.efternavn = efternavn

    def hils(self):
        return "Hej med dig jeg hedder %s" % self.fornavn

kaj = SimpelPerson('Kaj', 'Frøben')
andrea = SimpelPerson('Andrea', 'Fuglsang')

print kaj.efternavn # Frøben
print andrea.efternavn # Fuglsang
print kaj.hils() # Hej med dig jeg hedder Kaj
kaj.alder = 40
print kaj.alder # 40

Bare fortsat i samme fil:

class Person(object):

    fornavn = None
    efternavn = None
    alder = 0
    ilive = True
    venner = []

    def __init__(self, fornavn, efternavn, alder=0):
        self.fornavn = fornavn
        self.efternavn = efternavn
        self.alder = alder

    def hils(self):
        return "Hej med dig jeg hedder %s" % self.fornavn

    def er_voksen(self):
        return self.alder >= 18

    def doe(self):
        self.ilive = False

    def ven(self, ven):
        self.venner.append(ven)

kaj = Person('Kaj', 'Frøben', alder=40)
andrea = Person('Andrea', 'Fuglsang', alder=40)
poul = Person('Poul', 'Kjøller')

print kaj.er_voksen() # True
print poul.er_voksen() # False (han er pt kun 0 år..)
poul.alder = 62
poul.doe() # han er desværre død
print poul.er_voksen() # True
print poul.ilive # False

kaj.ven( andrea )
kaj.ven( poul )

print "%s har %s venner" % (kaj.fornavn, len( kaj.venner )) # Kaj har 2 venner

for ven in kaj.venner:
    print ven.fornavn # Andrea + Poul
    print ven.hils() # Hej med dig jeg hedder Andrea + Hej med dig jeg hedder Poul

Javascript

Javascript ikke kan kreere en ‘class’, men er baseret på ‘prototype’. Der vil jeg ikke bruge meget tid på, heller ikke på de forskellige måder at man kan få Javascript til at opføre sig som om den kender til ‘klassiske klasser’. Vi holder det lige simpel:

var SimpelPerson = function(fornavn, efternavn) {
    this.fornavn = fornavn;
    this.efternavn = efternavn;

    this.hils = function() {
        return "Hej med dig jeg hedder " + this.fornavn;
    }
};
kaj = new SimpelPerson('Kaj', 'Frøben');
andrea = new SimpelPerson('Andrea', 'Fuglsang');

console.log( kaj.efternavn ); // Frøben
console.log( andrea.efternavn ); // Fuglsang
console.log( kaj.hils() ); // Hej med dig jeg hedder Kaj
kaj.alder = 40;
console.log( kaj.alder ); // 40

Bare fortsat i samme fil:

var Person = function(fornavn, efternavn, valgfrit) {
    var valgmuligheder = valgfrit || {};

    this.fornavn = fornavn;
    this.efternavn = efternavn;
    this.alder = valgmuligheder.alder || 0;
    this.iliv = true;
    this.venner = [];

    this.hils = function() {
        return "Hej med dig jeg hedder " + this.fornavn;
    };

    this.er_voksen = function() {
        return this.alder >= 18;
    };

    this.doe = function() {
        this.ilive = false;
    };

    this.ven = function(ven) {
        this.venner.push(ven)
    };
};

var kaj = new Person('Kaj', 'Frøben', {'alder':40});
var andrea = new Person('Andrea', 'Fuglsang', {'alder':40});
var poul = new Person('Poul', 'Kjøller');

console.log( kaj.er_voksen() ); // true
console.log( poul.er_voksen() ); // false (han er pt kun 0 år..)
poul.alder = 62;
poul.doe(); // han er desværre død
console.log( poul.er_voksen() ); // true
console.log( poul.ilive ); // false

kaj.ven( andrea );
kaj.ven( poul );

console.log( kaj.fornavn + " har " + kaj.venner.length +" venner" ) // Kaj har 2 venner

for( var i=0, len=kaj.venner.length; i<len; i++ ) {
    var ven = kaj.venner[i];
    console.log( ven.fornavn ); // Andrea + Poul
    console.log( ven.hils() ); // Hej med dig jeg hedder Andrea + Hej med dig jeg hedder Poul
}

PHP

<?php

class SimpelPerson{

    public $fornavn;
    public $efternavn;

    public function __construct($fornavn, $efternavn) {
        $this->fornavn = $fornavn;
        $this->efternavn = $efternavn;
    }

    public function hils() {
        return sprintf("Hej med dig jeg hedder %s", $this->fornavn);
    }

}

$kaj = new SimpelPerson('Kaj', 'Frøben');
$andrea = new SimpelPerson('Andrea', 'Fuglsang');

print( $kaj->efternavn ); // Frøben
print( $andrea->efternavn ); // Fuglsang
print( $kaj->hils() ); // Hej med dig jeg hedder Kaj
$kaj->alder = 40;
print( $kaj->alder ); // 40

Lige nu viser jeg lige hvordan man kan anvende PHP i praksis, som jeg ikke har gjort for Python og Javascript.

class.person.php:

<?php

class Person{

    public $fornavn;
    public $efternavn;
    public $alder = 0;
    public $ilive = true;
    public $venner = array();

    public function __construct($fornavn, $efternavn, $alder=0) {
        $this->fornavn = $fornavn;
        $this->efternavn = $efternavn;
        $this->alder = $alder;
    }

    public function hils() {
        return sprintf("Hej med dig jeg hedder %s", $this->fornavn);
    }

    public function er_voksen() {
        return $this->alder >= 18;
    }

    public function doe() {
        $this->ilive = false;
    }

    public function ven($ven) {
        $this->venner[] = $ven;
    }

}

kajs-venner.php:

<?php

include_once 'class.person.php';


$kaj = new Person('Kaj', 'Frøben', 40);
$andrea = new Person('Andrea', 'Fuglsang', 40);
$poul = new Person('Poul', 'Kjøller');
$poul->alder = 62; # ellers vil han være 0 år..
$poul->doe();  # han er desværre død

$kaj->ven( $andrea );
$kaj->ven( $poul );
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Kajs venner</title>
</head>
<body>
    <h1><?php echo $kaj->hils(); ?></h1>
    <p>Dem her, er mine venner:</p>
    <table border="1">
        <tr>
            <th>Navn</th>
            <th>Alder</th>
            <th>I live</th>
        </tr>
    <?php foreach ($kaj->venner as $ven) : ?>
        <tr>
            <td><?php echo $ven->fornavn . " " . $ven->efternavn; ?></td>
            <td><?php echo $ven->alder; ?> år</td>
            <td><?php echo $ven->ilive ? "Ja" : "Nej"; ?></td>
        </tr>
    <?php endforeach; ?>
    </table>
</body>
</html>

Den sidste fil giver denne tabel som resultat:

Navn Alder I live
Andrea Fuglsang 40 år Ja
Poul Kjøller 62 år Nej