Javas programmā atpazīt šādas lietas:

public class Employee {
public String name = "";
public double salary;
public Date birthDate;
public String getDetails() { ... }
}

public class Manager {
public String name = "";
public double salary;
public Date birthDate;
public String department;
public String getDetails() { ... }
}

public class Employee {
public String name = "";
public double salary;
public Date birthDate;
public String getDetails() { ... }
}
public class Manager extends Employee {
public String department;
}
modifier class name [extends superclass] declarations*

Mainīgie un metodes var atrasties vienā no 4 piekļuves līmeņiem: public, protected, noklusētajā (pakotnes) un private. Klases var būt vienīgi public vai noklusētajā (pakotnes) līmenī.
protected līmenis dod mainīgajam vai metode plašāku piekļuvi, nekā noklusētais līmenis. Abos gadījumos mainīgos vai metodes var izmantot tajā pašā pakotnē (package friendly). Toties protected, atšķirībā no noklusētā līmeņa, ļauj piekļuvi arī visiem, kuri no šīs klases manto - pat ja tie ir citā pakotnē.
Sk. visu 4 modifikatoru piekļuves ierobežojumu apkopojumu tabulā:
| Piekļuves modificētājs | Pati klase | Šīs klases pakotne | Apakšklase | Citas klases |
| private | Jā | Nē | Nē | Nē |
| default | Jā | Jā | Nē | Nē |
| protected | Jā | Jā | Jā | Nē |
| public | Jā | Jā | Jā | Jā |
Ievērojiet, ka ir iespējamas arī metodes ar to pašu vārdu un atšķirīgiem argumentu sarakstiem - tas nozīmē, ka šīm metodēm ir kopīgs vienīgi pārslogots (overloaded) nosaukums, bet tās ir citādi nesaistītas metodes. Ar objektorientāciju nesaistītajai metodes vārda pārslogošanai nav sakara ar objektorientētajai programmēšanai raksturīgo metodes pārdefinēšanu, kas - mantotās metodes uzvedības izmaiņu bērnu klasē).
public class Employee {
protected String name;
protected double salary;
protected Date birthDate;
public String getDetails() {
return "Name: " + name + "\n" +
"Salary: " + salary;
}
}
public class Manager extends Employee {
protected String department;
public String getDetails() {
return "Name: " + name + "\n" +
"Salary: " + salary + "\n" +
"Manager of: " + department;
}
}
public class Employee {
private String name;
private double salary;
private Date birthDate;
public String getDetails() {
return "Name: " + name + "\nSalary: " + salary;
}
}
public class Manager extends Employee {
private String department;
public String getDetails() {
// call parent method
return super.getDetails() +
"\nDepartment: " + department;
}
}
Sacīdami, ka pārvaldnieks ir darbinieks, t.i. Manager ir (IS AN) Employee, nozīmē, ka Manager'am piemīt visi tie paši atribūti un metodes, kas vecāku klasei. Tātad, katra operācija, kura ir atļauta uz Employee objekta ir atļauta arī uz Manager objekta.
Varētu šķist, ka radīt Manager'u un piešķirt tā referenci Employee'a tipa mainīgajam ir nemērķtiecīgi. Tomēr tas ir iespējams un ir iemesli, kāpēc to dara.
Employee employee = new Manager(); // pareizi // neatļauts mēģinājums piešķirt "Manager" atribūtam vērtību employee.department = "Sales"; // mainīgā tips ir "Employee", tāpēc šī darbība ir liegta pat tad, // ja konkrētajam objektam šis atribūts piemīt
Virtuālās metodes izsaukuma piemērs:
Employee e = new Manager(); e.getDetails();
Vajadzīga tipu pārbaude gan kompilācijas laikā, gan izpildes laikā
Valodā C++ šādu uzvedību nodrošināja tikai tad, ja metode tika deklarēta kā "virtual". Tas ļauj reizēm ietaupīt resursus, bet pat daļēja atteikšanās no pārdefinēto metožu virtuālās uzvedības nav raksturīga objektorientācijas paradigmai.
Šajā nepareizajā piemērā ir attēlotas absurdības, kuras varētu rasties, ja piekļuves tipu varētu sašaurināt.
public class Parent {
public void doSomething() {}
}
public class Child extends Parent {
private void doSomething() {}
}
public class UseBoth {
public void doOtherThing() {
Parent p1 = new Parent();
Parent p2 = new Child();
p1.doSomething();
p2.doSomething();
}
}
Vienāda tipu objektu kolekcijas sauc par homogēnām kolekcijām:
MyDate[] dates = new MyDate[2]; dates[0] = new MyDate(22, 12, 1964); dates[1] = new MyDate(22, 7, 1964);
Dažādu tipu objektu kolekcijas sauc par heterogēnām kolekcijām:
Employee [] staff = new Employee[1024]; staff[0] = new Manager(); staff[1] = new Employee(); staff[2] = new Engineer();
Tā kā Manager ir Employee:
// metode Employee klasē
public TaxRate findTaxRate(Employee e) {
}
// Izsaukums varbūt kādā citā aplikācijas klasē
Manager m = new Manager();
TaxRate t = findTaxRate(m);
public class Employee extends Object
public class Manager extends Employee
public class Engineer extends Employee
----------------------------------------
public void doSomething(Employee e) {
if (e instanceof Manager) {
// Apstrādā Manager'u
} else if (e instanceof Engineer) {
// Apstrādā Engineer'u
} else {
// Apstrādā citus Employee tipus
}
}
Šāda tipa kods ir riskants, ja tas neņem vērā situācijas, kur objektu mantošanas hierarhija laika gaitā varētu paplašināties. Tādēļ labāk ir pēc iespējas izmantot standarto metožu pārdefinēšanas mehānismu, nevis vienā metodē šķirot gadījumus ar instanceof operatoru.
Lietot sekojoši:
public void println(int i) public void println(float f) public void println(String s)
Argumentu sarakstiem parasti būtu jābūt "pietiekami" dažādiem, lai nerastos pārpratumi saistībā ar noklusētajiem, paplašinošajiem tipu pārveidojumiem, piemēram, no float uz double, jo tie var programmētājam radīt sajukumu.
Konstruktorus tāpat kā metodes var pārslogot. Piemērs:
public Employee(String name, double salary, Date DoB) { ... }
public Employee(String name, double salary) { ... }
public Employee(String name, Date DoB) { ... }
1 public class Employee {
2 private static final double BASE_SALARY = 15000.00;
3 private String name;
4 private double salary;
5 private Date birthDate;
6
7 public Employee(String name, double salary, Date DoB) {
8 this.name = name;
9 this.salary = salary;
10 this.birthDate = DoB;
11 }
12 public Employee(String name, double salary) {
13 this(name, salary, null);
14 }
15 public Employee(String name, Date DoB) {
16 this(name, BASE_SALARY, DoB);
17 }
18 public Employee(String name) {
19 this(name, BASE_SALARY);
20 }
21 // more Employee code...
22 }
1 public class Employee {
2 private static final double BASE_SALARY = 15000.00;
3 private String name;
4 private double salary;
5 private Date birthDate;
6
7 public Employee(String name, double salary, Date DoB) {
8 this.name = name;
9 this.salary = salary;
10 this.birthDate = DoB;
11 }
12 public Employee(String name, double salary) {
13 this(name, salary, null);
14 }
15 public Employee(String name, Date DoB) {
16 this(name, BASE_SALARY, DoB);
17 }
18 public Employee(String name) {
19 this(name, BASE_SALARY);
20 }
21 // more Employee code...
22 }
1 public class Manager extends Employee {
2 private String department;
3
4 public Manager(String name, double salary, String dept) {
5 super(name, salary);
6 department = dept;
7 }
8 public Manager(String n, String dept) {
9 super(name);
10 department = dept;
11 }
12 public Manager(String dept) { // Nepareizi, jo nav bezargumentu super()
13 department = dept;
14 }
15 }
public class Object {
...
public Object() {}
...
}
public class Employee extends Object {
private String name;
private double salary = 15000.00;
private Date birthDate;
public Employee(String n, Date DoB) {
// implicit super();
name = n;
birthDate = DoB;
}
public Employee(String n) {
this(n, null);
}
}
public class Manager extends Employee {
private String department;
public Manager(String n, String d) {
super(n);
department = d;
}
}
1 public class Employee extends Object {
2 private String name;
3 private double salary = 15000.00;
4 private Date birthDate;
5 private String summary;
6
7 public Employee(String n, Date DoB) {
8 name = n;
9 birthDate = DoB;
10 summary = getDetails();
11 }
12 public Employee(String n) {
13 this(n, null);
14 }
15
16 public String getDetails() {
17 return "Name: " + name + "\nSalary: " + salary
18 + "\nBirth Date: " + birthDate;
19 }
20 }
1 public class Manager extends Employee {
2 private String department;
3
4 public Manager(String n, String d) {
5 super(n);
6 department = d;
7 }
8
9 public String getDetails() {
10 return super.getDetails() + "\nDept: " + department;
11 }
12 }
Konstruējot Manager objektu, vadība nonāk Employee klases 10. rindiņā. Tur esošais getDetails() izsaukums noved pie Manager metodes getDetails() izsaukuma, lai gan department vēl nav Manager konstruktorā inicializēts. Šajā piemērā iekš "summary" iedrukās "null" norādītā departamenta vietā.
Lai no šādām situācijām izvairītos, var izmantot šādu ieteikumu: "Ja konstruktorā ir jāsauc metode, padariet šo metodi privātu".
public class Employee {
...
}
ir tas pats, kas
public class Employee extends Object {
...
}
1 public class MyDate {
2 private int day;
3 private int month;
4 private int year;
5
6 public MyDate(int day, int month, int year) {
7 this.day = day;
8 this.month = month;
9 this.year = year;
10 }
11
12 public boolean equals(Object o) {
13 boolean result = false;
14 if ( (o != null) && (o instanceof MyDate) ) {
15 MyDate d = (MyDate) o;
16 if ( (day == d.day) && (month == d.month)
17 && (year == d.year) ) {
18 result = true;
19 }
20 }
21 return result;
22 }
23
24 public int hashCode() {
25 return ( (new Integer(day).hashCode())
26 ^ (new Integer(month).hashCode())
27 ^ (new Integer(year).hashCode())
28 );
29 }
30 }
1 class TestEquals {
2 public static void main(String[] args) {
3 MyDate date1 = new MyDate(14, 3, 1976);
4 MyDate date2 = new MyDate(14, 3, 1976);
5
6 if ( date1 == date2 ) {
7 System.out.println("date1 un date2 ir identiski");
8 } else {
9 System.out.println("date1 un date2 nav identiski");
10 }
11
12 if ( date1.equals(date2) ) {
13 System.out.println("date1 un date2 ir vienādi");
14 } else {
15 System.out.println("date1 un date2 nav vienādi");
16 }
17
18 System.out.println("piešķir date2 = date1;");
19 date2 = date1;
20
21 if ( date1 == date2 ) {
22 System.out.println("date1 un date2 ir identiski");
23 } else {
24 System.out.println("date1 un date2 nav identiski");
25 }
26 }
27 }
Izvade:
date1 un date2 nav identiski date1 un date2 ir vienādi piešķir date2 = date1; date1 un date2 ir identiski
Uzlūko vienkāršos datu tipus kā objektus
| Vienkāršais datu tips | Iesaiņotājklase |
| boolean | java.lang.Boolean |
| byte | java.lang.Byte |
| char | java.lang.Character |
| short | java.lang.Short |
| int | java.lang.Integer |
| long | java.lang.Long |
| float | java.lang.Float |
| double | java.lang.Double |
int pInt = 500; Integer wInt = new Integer(pInt); int p2 = wInt.intValue();
Javas programmā prast atpazīt: