javabog.dk  |  << forrige  |  indhold  |  næste >>  |  eksempler

6 Pakker

Indhold:

Kapitlet forudsættes ikke i resten af bogen, men er ofte en fordel, når man skal programmere i praksis.

Forudsætter kapitel 4, Definition af klasser.



Når man laver større programmer (over 30-40 klasser), kan det være nyttigt at opdele dem i grupper. En pakke er en samling af klasser, der på en eller anden måde er beslægtede.

En pakke er en navngiven samling af klasser

Javas standardbibliotek på mere end 1000 klasser er delt op i ca. 30 mindre pakker.

Pakker svarer til (klasse)biblioteker i C eller C++ eller "unit"-begrebet i PASCAL.

6.1 At importere klassedefinitioner

Vi har set, at når vi skal benytte klasser, der ligger ud over de helt grundlæggende, bliver vi nødt til at meddele oversætteren, hvor den kan forvente at finde definitionen af klassen. Dette kaldes at importere klassen.

Egentlig kunne vi godt helt udelade import-sætninger og skrive det fulde pakke- og klassenavn hver gang. Hvis vi f.eks. vil benytte Vector-klassen, kunne vi skrive:

    java.util.Vector v;
    v = new java.util.Vector();

Det er jo lidt besværligt, og derfor kan vi vælge øverst i kildetekstfilen at skrive:

import java.util.Vector; 

Dette får oversætteren til at lede i java.util-pakken, hvis den møder en klasse, den ikke umiddelbart genkender. Nu kan vi skrive, som vi plejer:

    Vector v;
    v = new Vector();



Der kan forekomme et hvilket som helst antal import-sætninger i en javafil. Import-sætninger skal stå først i filen, før klassedefinitionen. Hvis man ønsker at importere flere klassedefinitioner fra samme pakke, kan man skrive en * i stedet for klassenavnet:

import java.util.*; 

Dermed importerer man samtlige klasser fra denne pakke. Det vil sige, at oversætteren leder denne pakke igennem, når den møder en klasse, den ikke umiddelbart genkender. De klassedefinitioner, der ikke bruges, bliver altså bare ignoreret.

Import af en klasse gør blot definitionen af klassen kendt for oversætteren - det gør ikke det færdige program større eller langsommere

6.2 Standardpakkerne

I Javas indbyggede hjælpesystem kan man se de forskellige indbyggede pakker, der indeholder en række nyttige klasser. De vigtigste standardpakker er:

Hvorfor hedder den sidste javax? javax betød oprindeligt, at det var en udvidelse til sproget, som ikke var en del af det egentlige standardbibliotek, og som måske aldrig bliver det. Efterhånden er en del javax-pakker (som javax.swing) dog alligevel kommet med.

Et andet eksempel er javax.comm, som er en kommunikationspakke, der håndterer seriel og parallel transmission af data. Denne pakke er ikke kommet med i standardbiblioteket.

6.2.1 Pakken java.lang

De mest basale javaklasser, eksempelvis String, ligger i pakken java.lang. Denne særlige pakke indeholder en masse grundfunktioner og importeres altid af oversætteren. Det er altså ikke nødvendigt at importere den eksplicit med import java.lang.*;

Af andre klasser i java.lang kan nævnes System (til f.eks. System.out.println()) og Math (til f.eks. Math.random() og Math.sqrt()).

6.3 Placering på filsystemet

Hvis vi husker, at en pakke er en navngiven samling af klasser, er det nærliggende at tænke på, hvordan filer er organiseret i underkataloger på et filsystem.

En klasse svarer til en fil på filsystemet
En pakke svarer til et underkatalog på filsystemet

For eksempel findes klassen java.util.Vector som filen Vector.class i et katalog, der hedder util, som er et underkatalog til et katalog, der hedder java: java/util/Vector.class (i Windows: java\util\Vector.class).

Ofte er klasserne og katalogerne pakket sammen i et såkaldt Java-arkiv (.jar-fil). jar-filer minder meget om zip-filer.

Oversætteren skal kende pakkens fysiske placering i filsystemet:

  1. Som et underkatalog med samme navn som pakken.

  2. I et underkatalog med samme navn som pakken et andet sted i filsystemet, som der henvises til med CLASSPATH-variablen.

  3. I en jar-fil, som der henvises til med CLASSPATH-variablen.

CLASSPATH-variablen er en miljøvariabel, der minder om PATH-variablen (defineret i AUTOEXEC.BAT i DOS). Den angiver de steder, hvor oversætteren skal lede efter klassedefinitioner.

6.4 At definere egne pakker

Man kan definere sine egne pakker. Dette er specielt brugbart i større systemer, hvor man har mange klasser med beslægtede funktioner, for eksempel kommunikation (internetkøb med VISA eller Dankort) eller sine egne matematik- eller datobearbejdningspakker.

Det er normalt at man benytter sin internetadresse eller firmanavn i navngivningen af pakkerne. F.eks: oracle.JDeveloper.layout.XYLayout (klassen er XYLayout, og pakken er oracle.JDeveloper.layout), com.sybase.jdbc.SybDriver eller netscape.javascript.JSObject.

6.4.1 Eksempel

I følgende eksempel findes to klasser, nemlig Klasse1 og Klasse2 i en pakke (der hedder minPakke). De bruges af den eksekverbare main()-klasse BenytPakker:

import minPakke.*;

public class BenytPakker
{
  public static void main(String[] arg)
  {
    Klasse1 a = new Klasse1();
    Klasse2 b = new Klasse2();
    a.snak();
    b.snak();
  }
}



Klasse1 og Klasse2 skal ligge i et underkatalog, der hedder minPakke:

// Filnavn: minPakke/Klasse1.java
package minPakke;

public class Klasse1
{
  public void snak()
  {
    System.out.println("Dette er Klasse1, der taler!");
  }
}



// Filnavn: minPakke/Klasse2.java
package minPakke;

public class Klasse2
{
  public void snak()
  {
    System.out.println("Dette er Klasse2, der taler!");
  }
}

6.5 Pakke klasser i jar-filer (Java-arkiver)

Laver man sine egne pakker, ønsker man ofte at kunne distribuere de oversatte .class-filer med nytekoden til andre. Det gøres nemmest ved at pakke filerne i en jar-fil.

En jar-fil skabes med et zip-værktøj som WinZip eller GnoZip til Linux eller fra kommandolinien med kommandoen jar, der følger med, når man installerer Java. Den minder meget om UNIX' tar-kommando. Man opretter et arkiv ved at skrive f.eks.:

  jar cf program.jar BenytPakker.class minPakke

Dette vil oprette jar-filen minPakke.jar med klassen BenytPakker.class og alle filerne i underkataloget minPakke (d.v.s. minPakke/Klasse1.class og minPakke/Klasse2.class).

Derefter kan main()-metoden i BenytPakker udføres ved at blot skrive

  java -cp program.jar BenytPakker

6.5.1 Eksekverbare jar-filer

Hvis man vil distribuere sit program til mange mennesker, kan det være bekvemt, at brugerne kan dobbeltklikke på jar-filen, lige som f.eks. Windows-brugere dobbeltklikker på .exe-filer. Det kræver, at man lægger en såkaldt manifest-fil med i jar-filen:

  jar cfm program.jar manifest.txt BenytPakker.class minPakke

Filen manifest.txt, der angiver klassen med main()-metoden, skal indeholde følgende:

Manifest-Version: 1.0
Main-Class: BenytPakker

Derefter kan man dobbeltklikke på program.jar eller fra kommandolinien blot skrive:

  java -jar program.jar

6.6 Test dig selv

  1. Hvad er en pakke?

  2. Hvordan bruger man klasser fra en pakke?

  3. Hvad er sammenhængen mellem pakkenavn og placering på filsystemet?

6.7 Resumé (kan læses i den trykte bog)

6.8 Opgaver

  1. Søg i din computer efter filer, der ender på .jar, og åbn dem med et program, der kan læse ZIP-komprimerede filer (f.eks unzip eller WinZip).
    Hvordan er filerne organiseret?

  2. Se, om du kan finde filen, der indeholder Vector-klassen.
    Hvilket underkatalog ligger den i?

  3. Opret nogle klasser i en pakke og en main()-klasse, der benytter dem
    (f.eks. BenytPakker.java, minPakke/Klasse1.java og minPakke/Klasse2.java).

  4. Pak dem i en jar-fil.

  5. Prøv at oprette en eksekverbar jar-fil.

Til de sidste tre opgaver kan det være en fordel at gå ind på den elektroniske udgave af bogen, http://javabog.dk og kopiere teksten i stedet for at taste den ind.

6.9 Avanceret - public, protected og private

Det er vigtigt at styre adgangen til at kalde metoder og ændre på variabler, i særdeleshed når programmerne bliver store. Det kan lette overskueligheden meget hvis interne variabler og metoder er skjult uden for klassen.

6.9.1 Variabler og metoder

Variabler og metoder erklæret public er altid tilgængelige inden for og uden for klassen.

Variabler og metoder erklæret protected er tilgængelige for alle klasser inden for samme pakke. Klasser i andre pakker kan kun få adgang, hvis de er nedarvinger.

Skriver man ingenting, er det kun klasser i samme pakke, der har adgang til variablen eller metoden.

Hvis en variabel eller metode er erklæret private, kan den kun benyttes inden for samme klasse (og kan derfor ikke tilsidesættes med nedarvning). Det er det mest restriktive.

Adgangen kan sættes på skemaform:



Adgang

public

protected

(ingenting)

private

i samme klasse

ja

ja

ja

ja

klasse i samme pakke

ja

ja

ja

nej

nedarving i en anden pakke

ja

ja

nej

nej

ej nedarving og i en anden pakke

ja

nej

nej

nej

Holder man sig inden for samme pakke, er der altså ingen forskel mellem public, protected og ingenting. Adgangskontrol ud over public/private bliver derfør først interessant, når der er mange klasser, og programmet spænder over flere pakker. Så kan klasserne inden for samme pakke virke nært sammen (f.eks. ændre i hinandens interne variabler), mens adgangen fra klasser i de andre pakker er begrænset. Se eventuelt kapitlet om pakker.

6.9.2 Klasser

Klasser kan erklæres public eller ingenting (men ikke protected eller private).

Klasser erklæres normalt public og er tilgængelige fra alle pakker.

public class X 
{
  // ...
}

Undlader man public, er klassen kun tilgængelig inden for samme pakke.

class X
{
  // ...
}

Man kan have flere klasser i en fil, men højst en, der er public, og denne klasse skal hedde det samme som filnavnet.




javabog.dk  |  << forrige  |  indhold  |  næste >>  |  eksempler
Jacob Nordfalk - Objektorienteret programmering i Java - http://javabog.dk - Licens og kopiering under Åben Dokumentlicens (ÅDL)