Java >> Java tutorial >  >> Java

Objektorienteret programmering i Java – En begyndervejledning

Hej folkens! I dag skal vi tale om objektorienteret programmering i Java.

Denne artikel vil hjælpe med at give dig en grundig forståelse af de underliggende principper for objektorienteret programmering og dets koncepter.

Når du forstår disse begreber, bør du have tillid til og evne til at udvikle grundlæggende problemløsningsapplikationer ved hjælp af objektorienterede programmeringsprincipper i Java.

Hvad er objektorienteret programmering?

Objektorienteret programmering (OOP) er et grundlæggende programmeringsparadigme baseret på konceptet objekter . Disse objekter kan indeholde data i form af felter (ofte kendt som attributter eller egenskaber) og kode i form af procedurer (ofte kendt som metoder).

Kernen i den objektorienterede tilgang er at opdele komplekse problemer i mindre objekter.

I denne artikel vil vi se på følgende OOP-koncepter:

  1. Hvad er Java?
  2. Hvad er en klasse?
  3. Hvad er et objekt?
  4. Hvad er en Java Virtual Machine (JVM)?
  5. Sådan fungerer adgangsmodifikatorer i Java.
  6. Sådan fungerer konstruktører i Java.
  7. Sådan fungerer metoder i Java.
  8. Nøgleprincipper for OOP.
  9. Grænseflader i Java.

Hvad er Java?

Java er et klassebaseret, objektorienteret programmeringssprog til generelle formål, som fungerer på forskellige operativsystemer såsom Windows, Mac og Linux.

Du kan bruge Java til at udvikle:

  • Skrivebordsapplikationer
  • Webapplikationer
  • Mobilapplikationer (især Android-apps)
  • Web- og applikationsservere
  • Big databehandling
  • Indlejrede systemer

Og meget mere.

I Java starter hvert program med et klassenavn, og denne klasse skal matche filnavnet. Når du gemmer en fil, skal du gemme den ved at bruge klassenavnet og tilføje .java til slutningen af ​​filnavnet.

Lad os skrive et Java-program, der udskriver beskeden Hej freeCodeCamp-fællesskab. Mit navn er ... .

Vi starter med at lave vores første Java-fil kaldet Main.java, som kan gøres i enhver teksteditor. Efter at have oprettet og gemt filen, vil vi bruge nedenstående kodelinjer for at få det forventede output.

public class Main 
{
  public static void main(String[] args) 
  {
    System.out.println("Hello freeCodeCamp community. My name is Patrick Cyubahiro.");
  }
}

Bare rolig, hvis du ikke forstår ovenstående kode i øjeblikket. Vi vil diskutere, trin for trin, hver linje kode lige nedenfor.

Indtil videre vil jeg have dig til at starte med at bemærke, at hver linje kode, der kører i Java, skal være i en klasse.

Du kan også bemærke, at Java skelner mellem store og små bogstaver. Det betyder, at Java har mulighed for at skelne mellem store og små bogstaver. For eksempel variablen myClass og variablen min klasse er to helt forskellige ting.

Okay, lad os se, hvad den kode gør:

Lad os først se på main() metode:public static void main(String[] args) .

Denne metode er påkrævet i alle Java-programmer, og den er den vigtigste, fordi den er indgangspunktet for ethvert Java-program.

Dens syntaks er altid public static void main(String[] args) . Det eneste, der kan ændres, er navnet på string-array-argumentet. For eksempel kan du ændre args til myStringArgs .

Hvad er en klasse i Java?

En klasse er defineret som en samling af objekter. Du kan også tænke på en klasse som en plan, hvorfra du kan oprette et individuelt objekt.

For at oprette en klasse bruger vi nøgleordet class .

Syntaks for en klasse i Java:

class ClassName {
  // fields
  // methods
}

I ovenstående syntaks har vi felter (også kaldet variabler) og metoder, som repræsenterer henholdsvis objektets tilstand og adfærd.

Bemærk at vi i Java bruger felter til at gemme data, mens vi bruger metoder til at udføre operationer.

Lad os tage et eksempel:

Vi vil oprette en klasse ved navn Hoved med en variabel y . Variablen y vil gemme værdien 2.

public class Main { 

int y = 2; 

}

Bemærk, at en klasse altid skal starte med et stort første bogstav, og Java-filen skal matche klassenavnet.

Hvad er et objekt i Java?

Et objekt er en entitet i den virkelige verden, der tydeligt kan identificeres. Objekter har tilstande og adfærd. Med andre ord består de af metoder og egenskaber til at gøre en bestemt type data nyttig.

Et objekt består af:

  • En unik identitet: Hvert objekt har en unik identitet, selvom tilstanden er identisk med den for et andet objekt.
  • Stat/Egenskaber/Attributter: Tilstand fortæller os, hvordan objektet ser ud, eller hvilke egenskaber det har.
  • Adfærd: Adfærd fortæller os, hvad objektet gør.

Eksempler på objekttilstande og adfærd i Java:

Lad os se på nogle eksempler fra det virkelige liv på de tilstande og adfærd, som objekter kan have.

Eksempel 1:

  • Objekt:bil.
  • Tilstand:farve, mærke, vægt, model.
  • Adfærd:bryde, accelerere, dreje, skifte gear.

Eksempel 2:

  • Objekt:hus.
  • Stat:adresse, farve, placering.
  • Adfærd:åben dør, luk dør, åben persienner.

Syntaks for et objekt i Java:

public class Number {

int y = 10;

public static void main(String[] args) {

Number myObj = new Number();

System.out.println(myObj.y);

}

}

Hvad er Java Virtual Machine (JVM)?

Java Virtual Machine (JVM) er en virtuel maskine, der gør det muligt for en computer at køre Java-programmer.

JVM har to primære funktioner, som er:

  • At tillade Java-programmer at køre på enhver enhed eller operativsystem (dette er også kendt som "Skriv én gang, kør hvor som helst"-princippet).
  • Og for at administrere og optimere programhukommelsen.

Sådan fungerer adgangsmodifikatorer i Java

I Java er adgangsmodifikatorer nøgleord, der angiver tilgængeligheden af ​​klasser, metoder og andre medlemmer.

Disse nøgleord bestemmer, om et felt eller en metode i en klasse kan bruges eller påkaldes af en anden metode i en anden klasse eller underklasse.

Adgangsmodifikatorer kan også bruges til at begrænse adgangen.

I Java har vi fire typer adgangsmodifikatorer, som er:

  • Standard
  • Offentlig
  • Privat
  • Beskyttet

Lad os se på hver enkelt mere detaljeret nu.

Standardadgangsmodifikator

Standardadgangsmodifikatoren kaldes også pakke-privat. Du bruger det til at gøre alle medlemmer i den samme pakke synlige, men de kan kun tilgås inden for den samme pakke.

Bemærk, at når der ikke er angivet eller erklæret nogen adgangsmodifikator for en klasse, metode eller datamedlem, tager den automatisk standardadgangsmodifikatoren.

Her er et eksempel på, hvordan du kan bruge standardadgangsmodifikatoren:

class SampleClass 
{
    void output() 
       { 
           System.out.println("Hello World! This is an Introduction to OOP - 			Beginner's guide."); 
       } 
} 
class Main
{ 
    public static void main(String args[]) 
       {   
          SampleClass obj = new SampleClass(); 
          obj.output();  
       } 
}

Lad os nu se, hvad denne kode gør:

void output() :Når der ikke er nogen adgangsmodifikator, tager programmet automatisk standardmodifikatoren.

SampleClass obj = new SampleClass(); :Denne kodelinje giver programmet adgang til klassen med standardadgangsmodifikatoren.

obj.output(); :Denne kodelinje giver programmet adgang til klassemetoden med standardadgangsmodifikatoren.

Outputtet er:Hello World! This is an Introduction to OOP - Beginner's guide. .

Public Access Modifier

modifikatoren for offentlig adgang tillader en klasse, en metode eller et datafelt at være tilgængelig fra enhver klasse eller pakke i et Java-program. Offentlig adgangsmodifikator er tilgængelig i pakken såvel som uden for pakken.

Generelt begrænser en offentlig adgangsmodifikator overhovedet ikke entiteten.

Her er et eksempel på, hvordan offentlig adgangsmodifikator kan bruges:

// Car.java file
// public class
public class Car {
    // public variable
    public int tireCount;

    // public method
    public void display() {
        System.out.println("I am a Car.");
        System.out.println("I have " + tireCount + " tires.");
    }
}

// Main.java
public class Main {
    public static void main( String[] args ) {
        // accessing the public class
        Car car = new Car();

        // accessing the public variable
        car.tireCount = 4;
        // accessing the public method
        car.display();
    }
}

Output:

I am a Car.

I have 4 tires.

Lad os nu se, hvad der foregår i den kode:

I ovenstående eksempel,

  • Den offentlige klasse Car tilgås fra hovedklassen.
  • Den offentlige variabel tireCount tilgås fra hovedklassen.
  • Den offentlige metode display() tilgås fra hovedklassen.

Modifier for privat adgang

modifikatoren for privat adgang er en adgangsmodifikator, der har det laveste tilgængelighedsniveau. Det betyder, at de metoder og felter, der er erklæret som private, ikke er tilgængelige uden for klassen. De er kun tilgængelige inden for den klasse, der har disse private enheder som medlemmer.

Du kan også bemærke, at de private enheder ikke er synlige, selv for klassens underklasser.

Her er et eksempel på, hvad der ville ske, hvis du forsøger at få adgang til variabler og metoder, der er erklæret private uden for klassen:

class SampleClass 
{
    
    private String activity;
}

public class Main 
{

    public static void main(String[] main)
    {

        SampleClass task = new SampleClass();

        task.activity = "We are learning the core concepts of OOP.";
    }
}

Okay, hvad sker der her?

  1. private String activity :Modifikatoren for privat adgang gør variablen "aktivitet" til en privat.
  2. SampleClass task = new SampleClass(); :Vi har oprettet et objekt af SampleClass.
  3. task.activity = "We are learning the core concepts of OOP."; :På denne kodelinje forsøger vi at få adgang til den private variabel og feltet fra en anden klasse (som aldrig kan være tilgængelig på grund af den private adgangsmodifikator).

Når vi kører ovenstående program, får vi følgende fejl:

Main.java:49: error: activity has private access in SampleClass
        task.activity = "We are learning the core concepts of OOP.";
            ^
1 error

Dette er fordi vi forsøger at få adgang til den private variabel og felt fra en anden klasse.

Så den bedste måde at få adgang til disse private variabler på er at bruge getter- og setter-metoderne.

Gettere og sættere bruges til at beskytte dine data, især når du opretter klasser. Når vi opretter en getter-metode for hver instansvariabel, returnerer metoden sin værdi, mens en setter-metode angiver dens værdi.

Lad os se på, hvordan vi kan bruge getters og setters-metoden til at få adgang til den private variabel.

class SampleClass 
{

    private String task;

    // This is the getter method.
    public String getTask() 
    {
    
        return this.task;
    }
    
    // This is the setter method.
    public void setTask(String task) 
    {
    
        this.task= task;
    }
}

public class Main 
{

    public static void main(String[] main)
    {
    
        SampleClass task = new SampleClass();

        // We want to access the private variable using the getter and 				   setter.
        
        task.setTask("We are learning the core concepts of OOP.");
        
        System.out.println(task.getTask());
    }
}

Når vi kører ovenstående program, er dette output:

We are learning the core concepts of OOP.

Da vi har en privat variabel ved navn task i ovenstående eksempel har vi brugt metoderne getTask() og setTask() for at få adgang til variablen fra den ydre klasse. Disse metoder kaldes getter og setter i Java.

Vi har brugt setter-metoden (setTask() ) for at tildele værdi til variablen og getter-metoden (getTask() ) for at få adgang til variablen.

For at lære mere om this søgeord, kan du læse denne artikel her.

Modifier for beskyttet adgang

Når metoder og datamedlemmer erklæres protected , vi kan få adgang til dem inden for den samme pakke såvel som fra underklasser.

Vi kan også sige, at protected adgangsmodifikator ligner på en eller anden måde standardadgangsmodifikatoren. Det er bare, at det har en undtagelse, som er dets synlighed i underklasser.

Bemærk, at klasser ikke kan erklæres beskyttede. Denne adgangsmodifikator bruges generelt i et forældre-barn-forhold.

Lad os se på, hvordan vi kan bruge den beskyttede adgangsmodifikator:

// Multiplication.java

package learners;

public class Multiplication 
{

   protected int multiplyTwoNumbers(int a, int b)
   {
       
	return a*b;
	
   }
   
}

// Test.java

package javalearners;

import learners.*;

class Test extends Multiplication
{
    
   public static void main(String args[])
   {
       
	Test obj = new Test();
	
	System.out.println(obj.multiplyTwoNumbers(2, 4));
	
   }
   
} //output: 8

Hvad laver denne kode?

I dette eksempel er klassen Test som er til stede i en anden pakke er i stand til at kalde multiplyTwoNumbers() metode, som er erklæret beskyttet.

Metoden er i stand til at gøre det, fordi Test klasse udvider klassen Addition og protected modifikator tillader adgang til protected medlemmer i underklasser (i alle pakker).

Hvad er konstruktører i Java?

En konstruktør i Java er en metode, som du bruger til at initialisere nyoprettede objekter.

Syntaks for en konstruktør i Java:

public class Main { 

int a;  

public Main() { 

a = 3 * 3; 

} 

public static void main(String[] args) { 

Main myObj = new Main();

System.out.println(myObj.a); 

} 

} 

Så hvad sker der i denne kode?

  1. Vi er startet med at oprette Main klasse.
  2. Derefter har vi oprettet en klasseattribut, som er variablen a .
  3. For det tredje har vi oprettet en klassekonstruktør til hovedklassen.
  4. Derefter har vi indstillet startværdien for variabel a som vi har erklæret. Variablen a vil have en værdi på 9. Vores program vil kun tage 3 gange 3, hvilket er lig med 9. Du kan frit tildele en hvilken som helst værdi til variablen a . (I programmering betyder symbolet "*" multiplikation).

Hvert Java-program starter sin udførelse i main() metode. Så vi har brugt public static void main(String[] args) , og det er det punkt, hvorfra programmet starter sin eksekvering. Med andre ord, main() metoden er indgangspunktet for hvert Java-program.

Nu vil jeg forklare, hvad hvert søgeord i main() metode gør.

Det offentlige søgeord.

offentligheden søgeord er en adgangsmodifikator . Dens rolle er at specificere, hvorfra metoden kan tilgås, og hvem der har adgang til den. Så når vi laver main() metode offentlig, den gør den globalt tilgængelig. Med andre ord bliver den tilgængelig for alle dele af programmet.

Det statiske søgeord.

Når en metode er erklæret med en statisk søgeord, er det kendt som en statisk metode. Altså Java main() metoden er altid statisk så compileren kan kalde det uden eller før oprettelsen af ​​et objekt i klassen.

Hvis main() metode er tilladt at være ikke-statisk, så bliver Java Virtual Machine nødt til at instansiere sin klasse, mens den kalder main() metode.

Det statiske nøgleord er også vigtigt, da det sparer unødvendigt hukommelsesspild, som ville være blevet brugt af objektet, der kun er erklæret til at kalde main() metode af Java Virtual Machine.

The Void-søgeord.

tomrummet nøgleord er et nøgleord, der bruges til at angive, at en metode ikke returnerer noget. Hver gang main() metode forventes ikke at returnere noget, så er dens returtype ugyldig. Så det betyder, at så snart main() metoden afsluttes, afsluttes Java-programmet også.

Main.

Hoved er navnet på Java-hovedmetoden. Det er identifikatoren, som Java Virtual Machine leder efter som udgangspunktet for java-programmet.

String[] args .

Dette er en række strenge, der gemmer Java-kommandolinjeargumenter.

Det næste trin er at oprette et objekt af klassen Main. Vi har lavet et funktionskald, der kalder klassekonstruktøren.

Det sidste trin er at udskrive værdien af ​​a , hvilket er 9.

Sådan fungerer metoder i Java

En metode er en kodeblok, der udfører en bestemt opgave. I Java bruger vi termen metode, men i nogle andre programmeringssprog, såsom C++, er den samme metode almindeligvis kendt som en funktion.

I Java er der to typer metoder:

  • Brugerdefinerede metoder :Det er metoder, som vi kan skabe ud fra vores krav.
  • Standard biblioteksmetoder :Disse er indbyggede metoder i Java, som er tilgængelige til brug.

Lad mig give dig et eksempel på, hvordan du kan bruge metoder i Java.

Java-metodeeksempel 1:

class Main {

  // create a method
  public int divideNumbers(int x, int y) {
    int division = x / y;
    // return value
    return division;
  }

  public static void main(String[] args) {
    
    int firstNumber = 4;
    int secondNumber = 2;

    // create an object of Main
    Main obj = new Main();
    // calling method
    int result = obj.divideNumbers(firstNumber, secondNumber);
    System.out.println("Dividing " + firstNumber + " by " + secondNumber + " is: " + result);
  }
}

Output:

Dividing 4 by 2 is: 2

I ovenstående eksempel har vi lavet en metode ved navn divideNumbers() . Metoden tager to parametre x og y, og vi har kaldt metoden ved at sende to argumenter firstNumber og secondNumber .

Nu hvor du kender nogle grundlæggende Java-principper, så lad os se på objektorienterede programmeringsprincipper lidt mere i dybden.

Nøgleprincipper for objektorienteret programmering.

Der er de fire hovedprincipper i det objektorienterede programmeringsparadigme. Disse principper er også kendt som søjlerne i objektorienteret programmering.

De fire hovedprincipper for objektorienteret programmering er:

  1. Indkapsling (jeg vil også kort berøre informationsskjul)
  2. Arv
  3. Abstraktion
  4. Polymorfi

Indkapsling og informationsskjul i Java

Indkapsling er, når du samler dine data under en enkelt enhed. Enkelt sagt er det mere eller mindre som et beskyttende skjold, der forhindrer dataene i at blive tilgået af koden uden for dette skjold.

Et simpelt eksempel på indkapsling er en skoletaske. En skoletaske kan opbevare alle dine ting på ét sted, såsom dine bøger, kuglepenne, blyanter, lineal og meget mere.

Informationsskjul eller dataskjul i programmering handler om at beskytte data eller information mod enhver utilsigtet ændring i hele programmet. Dette er en kraftfuld objektorienteret programmeringsfunktion, og den er tæt forbundet med indkapsling.

Ideen bag indkapsling er at sikre, at "sensitive " data er skjult for brugere. For at opnå dette skal du:

  1. Erklær klassevariabler/attributter som private .
  2. Giv offentlig get og set metoder til at få adgang til og opdatere værdien af ​​en private variabel.

Som du husker, private variabler kan kun tilgås inden for den samme klasse, og en ekstern klasse kan ikke få adgang til dem. De kan dog tilgås, hvis vi leverer offentlig get og set metoder.

Lad mig give dig et yderligere eksempel, der viser, hvordan get og set metoder virker:

public class Student {
  private String name; // private = restricted access

  // Getter
  public String getName() {
    return name;
  }

  // Setter
  public void setName(String newName) {
    this.name = newName;
  }
}

Arv i Java

Nedarvning giver klasser mulighed for at arve attributter og metoder fra andre klasser. Det betyder, at forældreklasser udvider egenskaber og adfærd til børneklasser. Nedarvning understøtter genbrug.

Et simpelt eksempel, der forklarer begrebet arv, er, at mennesker (generelt) arver visse egenskaber fra klassen "Menneske", såsom evnen til at tale, trække vejret, spise, drikke og så videre.

Vi grupperer "arvebegrebet" i to kategorier:

  • underklasse (barn) - den klasse, der arver fra en anden klasse.
  • superklasse (forælder) - klassen, der nedarves fra.

For at arve fra en klasse bruger vi extends søgeord.

I eksemplet nedenfor er JerryTheMouse klasse oprettes ved at arve metoderne og felterne fra Animal klasse.

JerryTheMouse er underklassen og Animal er superklassen.

class Animal {

  // field and method of the parent class
  String name;
  public void eat() {
    System.out.println("I can eat");
  }
}

// inherit from Animal
class JerryTheMouse extends Animal {

  // new method in subclass
  public void display() {
    System.out.println("My name is " + name);
  }
}

class Main {
  public static void main(String[] args) {

    // create an object of the subclass
    JerryTheMouse labrador = new JerryTheMouse();

    // access field of superclass
    mouse.name = "Jerry, the mouse";
    mouse.display();

    // call method of superclass
    // using object of subclass
    mouse.eat();

  }
}

Output:

My name is Jerry

I can eat

Abstraktion i Java

Abstraktion er et koncept i objektorienteret programmering, der lader dig vise kun væsentlige attributter og skjuler unødvendig information i din kode. Hovedformålet med abstraktion er at skjule unødvendige detaljer for dine brugere.

Et simpelt eksempel til at forklare abstraktion er at tænke over den proces, der kommer i spil, når du sender en e-mail. Når du sender en e-mail, er komplekse detaljer, såsom hvad der sker, så snart den er sendt, og den protokol, som serveren bruger, skjult for dig.

Når du sender en e-mail, skal du blot indtaste e-mail-adressen på modtageren, e-mail-emnet, indtaste indholdet og klikke på send.

Du kan abstrakte ting ved at bruge abstrakte klasser eller grænseflader .

abstract nøgleordet er en ikke-adgangsmodifikator, der bruges til klasser og metoder:

  • Abstrakt klasse: er en begrænset klasse, der ikke kan bruges til at oprette objekter. For at få adgang til den skal den arves fra en anden klasse.
  • Abstrakt metode: En metode, der ikke har sin krop, er kendt som en abstrakt metode. Vi bruger den samme abstract nøgleord til at skabe abstrakte metoder.

Brødteksten af ​​en abstrakt metode leveres af underklassen (nedarvet fra).

Eksempel:

// Abstract class
abstract class Animal {
  // Abstract method (does not have a body)
  public abstract void animalSound();
  // Regular method
  public void sleep() {
    System.out.println("Zzzz");
  }
}

// Subclass (inherit from Animal)
class Cow extends Animal {
  public void animalSound() {
    // The body of animalSound() is provided here
    System.out.println("The cow says: Moo");
  }
}

class Main {
  public static void main(String[] args) {
    Cow myCow = new Cow(); // Create a Cow object
    myCow.animalSound();
    myCow.sleep();
  }
}

Polymorfisme i Java

Polymorfi refererer til et objekts evne til at antage mange former. Polymorfi opstår normalt, når vi har mange klasser, der er relateret til hinanden ved arv.

Polymorfi ligner, hvordan en person kan have forskellige egenskaber på samme tid.

For eksempel kan en mand være en far, en bedstefar, en mand, en medarbejder og så videre – alt sammen på samme tid. Så den samme person har forskellige egenskaber eller adfærd i forskellige situationer.

Eksempel:

Vi skal lave objekter Ko og Kat og kalde animalSound() metode på hver af dem.

class Animal {
  public void animalSound() {
    System.out.println("An animal can make a sound.");
  }
}

class Cow extends Animal {
  public void animalSound() {
    System.out.println("A cow says: Moooo");
  }
}

class Cat extends Animal {
  public void animalSound() {
    System.out.println("A cat says: Meeooww");
  }
}

class Main {
  public static void main(String[] args) {
    Animal myAnimal = new Animal();
    Animal myCow = new Cow();
    Animal myCat = new Cat();
        
    myAnimal.animalSound();
    myCow.animalSound();
    myCat.animalSound();
  }
}

Arv og polymorfi er meget nyttige til genanvendelighed af kode. Du kan genbruge attributterne og metoderne for en eksisterende klasse, når du opretter en ny klasse.

Grænseflader i Java

En interface er en samling abstrakte metoder. Med andre ord en interface er en fuldstændig "abstrakt klasse " bruges til at gruppere relaterede metoder med tomme brødtekster.

En grænseflade specificerer, hvad en klasse kan gøre, men ikke hvordan den kan gøre det.

Eksempel:

// create an interface
interface Language {
  void getName(String name);
}

// class implements interface
class ProgrammingLanguage implements Language {

  // implementation of abstract method
  public void getName(String name) {
    System.out.println("One of my favorite programming languages is: " + name);
  }
}

class Main {
  public static void main(String[] args) {
    ProgrammingLanguage language = new ProgrammingLanguage();
    language.getName("Java");
  }
}

Output:

One of my favorite programming languages is: Java

Konklusion

Vi har set på nogle af de vigtigste objektorienterede programmeringskoncepter i denne artikel. At have en god forståelse af disse begreber er afgørende, hvis du vil bruge dem godt og skrive god kode.

Jeg håber, at denne artikel var nyttig.

Mit navn er Patrick Cyubahiro, jeg er software- og webudvikler, UI/UX-designer, teknisk skribent og Community Builder.

Du er velkommen til at kontakte mig på Twitter:@Pat_Cyubahiro, eller skrive til:ampatrickcyubahiro[at]gmail.com

Tak fordi du læser og god læring!


Java tag