
Programmatūras veidošanā kopš pirmajām programmēšanas valodām ir centušies ievies atkalizmantojamu kodu (noslēpt mašīnvalodu sarežģītību un piedāvāt funkciju izsaukumus). Procedūras un funkcijas tika apkopotas bibliotēkās.
Agrīnās bibliotēkas manipulēja ar datiem kā ar atvērtām struktūrām (C valodas struct). Bibliotēkas izstrādātājs tad nevar noslēpt datu iekšējo uzbūvi. Arī bibliotēkas lietotājs bieži kļūst atkarīgs no datu struktūru iekšējām detaļām. 1980-to gadu beigās izplatījās C++ un objektorientētā programmēšana. Tajā procedūras asociēja ar datu struktūru un noslēpa implementācijas detaļas. Šādu datu un to apstrādes metožu kombināciju nosauca par klasi (class).
Mūsdienās funkciju bibliotēku analogs ir klašu bibliotēkas un API specifikācijas un karkasi (framework), kur lietotājs var izvēlēties dažādu piegādātāju implementācijas, tādējādi palielinot sava programmnodrošinājuma elastību un veiktspēju.
Javas platformu nemitgi papildina jauni API un specifikācijas, piemēram, Swing, JavaBeans, JDBC un daudzi citi.
Ietvarus var lietot oriģinālajā veidā un var arī paplašināt, lai paplašinātu tajos iebūvēto uzvedību ar jaunām iezīmēm. (Open-closed princips apgalvo, ka pielāgojumu klasēs, kuras manto no ietvara klasēm, nedrīkst mainīt ietvara klases uzvedību; to drīkst vienīgi paplašināt. No šejienes ir teiciens: Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. (Martin Fowler)
Priekšrocības, ja programmu dala mazākās daļās:
Dijkstras arguments: Ja c ir varbūtība, ka viena daļa ir uzprogrammēta pareizi un daļu pavisam ir N, tad varbūtība, ka visas N daļas kopā strādās pareizi ir cN. Šī varbūtība tiecas uz 0, ja N pieaug. (Dahl, Dijskstra, Hoare. "Structured Programming", 1972. Academic Press)
Viens pulksteņmeistars gatavo pulksteni vienā paņēmienā, bet otrs to veido pa moduļiem un moduļus pēc tam saliek kopā. Abiem pulksteņmeistariem reizēm zvana telefons - un attiecīgajā brīdī veidotais nepabeigtais salikums izjūk. Priekšrocības ir tam pulksteņmeistaram, kurš strādā hierarhiski - pa moduļiem. (Simon. "The Architecture of Complexity")
Lielu sistēmu var būvēt, atkārtojot rekursīvi šādus soļus:
Šāda pieeja ir izplatīta struktūrprogrammēšanā, tā pazīstama arī kā "top-down design" metode; līdzīgus spriešanas paņēmienus lietoja jau 17.gs. filozofs un matemātiķis R.Dekarts. (Divide each difficulty into as many parts as is feasible and necessary to resolve it., sk. Wikiquote.
Patvaļīgai daļās dalīšanai, ko realizē projektēšanas pieeja "no augšas uz leju" ir būtisks trūkums - tā neatbild uz jautājumu, vai pirmais dalījums ir labs, pirms neesam visu uzbūvējuši.
Cenšamies paturēt daļas vienādā abstrakcijas līmenī un samazināt mijietekmi (coupling) sastāvdaļu starpā - lai izmaiņas varētu veikt pēc iespējas neatkarīgi dažādajās daļās. Šo sauc arī par modularitātes principu objektorientētā projektēšanā.
Ražošanā projektējums ir apraksts, no kura konstruē fiziskos objektus. Programmatūras izstrādē klase ir projektējums objektiem:
T.i. objektorientētā programmēšanā pastāv objekti, kuri modelē kaut kādas reālās pasaules norises datora atmiņā (konkrētie objekti ir, piemēram, stringi, saraksti, datumi, apdrošināšanas polises, utml.). Savukārt klases ir šo konkrēto objektu abstrakcijas, kuras raksturo visiem noteikta veida objektiem (t.i. stringiem, sarakstiem, datumiem, polisēm, utml.) kopīgās īpašības un atļautās darbības ar tiem.
Javas tehnoloģijā klases atbalsta šādas 3 objektorientētās programmēšanas pamatiezīmes:
Javas klases sintakse:
<modifiers> class <class_name> [<attribute_declarations>] [<constructor_declarations>] [<method_declarations>]
Piemērs:
public class Vehicle {
private double maxLoad;
public void setMaxLoad(double value) {
maxLoad = value;
}
}
Atribūta sintakse:
<modifiers> <type> <name>;
Piemērs:
public class Foo {
private int x;
private float y = 10000.0F;
private String name = "Bates Motel";
}
Metožu deklarēšanas vispārīgā sintakse:
<modifiers> <return_type> <name> ([<argument_list>]) [<statements>]
Piemērs - metodes getWeight() un setWeight():
public class Dog {
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int newWeight) {
weight = newWeight;
}
}
Piemērs:
d.setWeight(42); d.weight = 42; // atļauts vienīgi tad, ja "weight" ir "public"
Aplūkosim šādu (sliktā, neobjektorientētā veidā projektētu) Javas klasi:

Klienta programmai (t.i. jebkuram kodam, kurš no ārpuses izmanto klasi MyDate) ir tieša pieeja šīs klases iekšējiem datiem:
MyDate d = new MyDate(); d.day = 32; // neesošs datums d.month = 2; d.day = 29; // grūtāk noskaidrot datuma esamību d.day = d.day + 1; // nepārbauda mēneša beigas
Uzlabots risinājums:

Klienta programmai jālieto setXxx()/getXxx() metodes, lai piekļūtu iekšējiem datiem:
MyDate d = new MyDate(); d.setDay(32); // nederīga diena, atgriež "false" d.setMonth(2); d.setDay(30); // intervāliem atbilst, bet aplami, // setDay atriž vērtību "false" d.setDay(d.getDay() + 1); // atgriež "false", ja ir mēneša beigas
Lietojot iekapsulēšanu, klases MyDate iekšējo uzbūvi var mainīt (vienu privāto atribūtu vietā ieviešot citus utml.), bet ja nebūs izmainījusies publisko metožu uzvedība, šīs izmaiņas klases lietotāji nepamanīs.

Konstruktora sintakse
<modifier> <class_name> ([<argument_list>]) [<statements>]
Piemērs
1 public class Dog {
2 private int weight;
3
4 public Dog() {
5 weight = 42;
6 }
7
8 public int getWeight() {
9 return weight;
10 }
11 public void setWeight(int newWeight) {
12 weight = newWeight;
13 }
14 }
1 public class TestDog {
2 public static void main(String[] args) {
3 Dog d = new Dog();
4 d.setWeight(42);
5 System.out.println("Dog d's weight is " + d.getWeight());
6 }
7 }
Ikviens Javas fails ir ar sekojošu struktūru - vispirms pakotnes deklarācija, tad importa deklarācijas, visbeidzot viena (izņēmuma gadījumos vairākas) klašu deklarācijas. Katrā Javas failā var deklarēt tikai vienu "public" klasi, kuras vārdam ir jāsakrīt ar *.java faila nosaukumu.
[<package_declaration>] [<import_declarations>] <class_declaration>+
Piemērs: fails VehicleCapacityReport.java:
package shipping.reports;
import shipping.domain.*;
import java.util.List;
import java.io.*;
public class VehicleCapacityReport {
private List vehicles;
public void generateReport(Writer output) {...}
}

Apakšpakotnes direktoriju struktūrā atbilst apakšdirektorijām. Tomēr katra pakotne ir pilnīgi neatkarīga no citām pakotnēm, neatkarīgi no to savstarpējā novietojuma direktoriju kokā. (Komandas package un import apstrādā individuāli, piemēram pakotnes java.awt un java.awt.event). Pakotņu un apakšpakotņu struktūra kalpo, lai milzīgajā klašu nosaukumu saimē ieviestu vārdapgabalus (namespace), t.i. logjiskas "vietas", kuru ietvaros klašu nosaukumi noteikti ir unikāli.
Vārdapgabali ir izplatīti arī ikdienas dzīvē. Piemēram, ielas nosaukums "Rīgas iela" nav viennozīmīgs - šādas ielas ir Sabilē, Jēkabpilī, Saldū, Salaspilī, Valmierā, u.c. Toties, līdzko izvēlamies vārdapgabalu (konkrētu pilsētu), tad visi ielu nosaukumi šīs pilsētas ietvaros ir unikāli.
Pakotnes komandas sintakse:
package <top_pkg_name>[.<sub_pkg_name>]*;
Piemērs:
package shipping.reports;
Importa komandas sintakse:
import <pkg_name>[.<sub_pkg_name>].<class_name>;
VAI
import <pkg_name>[.<sub_pkg_name>].*;
Piemēri:
import shipping.domain.*; import java.util.List; import java.io.*;


Kompilācija, lietojot karodziņu -d:
cd JavaProjects/BankPrj/src javac -d ../class banking/domain/*.java
set CLASSPATH=.;c:\JavaProjects\BankPrj\class;c:\JavaProjects\lib\biblioteka.jar java banking.GUI.BankingMain
java -classpath
c:\JavaProjects\BankPrj\class;c:\JavaProjects\lib\biblioteka.jar
banking.GUI.BankingMain
(šo komandu raksta vienā rindā)

Patvaļīgā Javas programmas izejas tekstā atrodiet šādas lietas:
Izmantojot Javas API dokumentāciju, atrodiet metodes klasei java.lang.String un java.lang.Object.