Sunteți pe pagina 1din 10

Lesson 3

Encapsulation, packages and inner classes

Mads Hjorth

2007

Kasper sterbye 2005 Carsten Schrmann 2004


1 OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

Coupling and cohesion


If nothing depends on your class, you can change if without consequences for the rest of the system. Such a class is said to be uncoupled (and most likely useless). If members of a class do not depend on each other, the class is said to have no cohesion (no togetherness) The goal is to design software with low coupling (not none) and high cohesion. The reason is that with low coupling, changes and errors in one location will not propagate to the rest of the code, with high cohesion, code that depends on each other is kept close to each other. Mechanisms to promote low coupling:

private fields renaming a field will not affect


anything outside the class. inside a package. outside the class.

non-public classes that can only be seen private methods that can not be called from
Mechanisms that allow high cohesion

all members are visible from inside a class. default visibility is package.

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

Access modifiers
The access modifiers for a member in class A:
private default only visible inside class A anywhere inside its own package, that is class A, B and C
C Package1 B A

protected anywhere inside its own package, but also inside subclasses; S public accessible from all classes in the system.

Package2 R S

The access modifiers for a class B:


default public the class will only be visible inside its own package; Package1 accessible from all classes in the system.

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

Beginners guide to access...


A set of guidelines to follow in most cases. With experience you will learn when to break the rules.
package dk.itu.oop.lesson1; public class Ball { private int x, y; private String color; public Ball(String color) { this.color = color; x = 0; y = 0; } public void move(int dx, int dy) { x += dx; y += dy; } public int getY() { return y; } public int getX() { return x; } }

make all fields private. make getter methods for all fields. Consider what setter methods are necessary. make methods as strict accessible as possible. private if possible, or default, or public. expose the purpose of the class by making methods public, possible also some fields.

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

Encapsulation
Here is a bare bone class for a Person:
class Person { String publicId; String name; String address; } public class Person { String publicId; String name; String address; public Person(String publicId, String name) { this.publicId = publicId; this.name = name; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }

We want to encapsulate the information in the class to allow only a restricted set of operation on the fields of a Person. After careful thinking we assume the following:

The publicId must be given when the person The name must be given when the person is

object is created and cannot be changed later. created. It is used by other classes and does not change. changed over time.

What problems do you see in the assumptions? What could be done to approve the class?
5

The address need not to be present and can be

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

Access and inheritance


If a method is redefined n a subclass, it must be at least as visible as in the superclass. The ruled is checked at compile time. The variable a is declared to be type of A, and in A the method is public. The call is legal. But the unaware to the compile we assign a to an instance of B, in which the method is declared private. Compile Error....
package dk.itu.oop.lesson3; class A { public int getANumber() { return 1; } } class B extends A { private int getANumber() { return 2; } }

// WRONG

class TestAB { public static void main(String[] args) { A a = new B(); int n = a.getANumber(); } }

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

The great freehand model....

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

Packages
All classes belong to exactly one package. If no package is specified it belongs to the default nameless package. The name of a package is a string (separated by .) e.g. java.lang, dk.itu.oop.lesson2. The fully qualified name of a class is the name of the package followed by a . followed by the name of the class. The fully qualified name of String is java.lang.String. Each class can declare what package it belongs to via the package declaration: package dk.itu.oop.lesson3;
package dk.itu.oop.lesson3; import dk.itu.oop.lesson1.Ball; import java.awt.*; import static java.lang.System.out; public class MovingBall extends Ball { private Component myComponent; public MovingBall(String color) { super(color); out.println("A ball is created"); } //... }

No concept of sub-packages. java.lang is not included in java There exist a relation between packages and directories in the default classloader.

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

Classpath
It is not specified in the Java language how to find all classes belonging to a package. It is up to a specific implementation of the abstract class ClassLoader to find the classes. The standard classloader from java command line use the environment variable classpath or the -cp argument to search for classes. If the classpath is set to X;Y;Z, the classloader will look for a class C in X. If is not found there it will look in Y, etc... If the class is in a package a.b.c then the classloader will look only for the class file in the file a/b/c/C.class Other classloaders looks in databases or in network locations.
X a b c Y pi C Y a b c C S
OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen 9

R S

Packages names
Each package should have a globally unique name to avoid name-space conflicts. You can create Universal Unique IDs using java.util.UUID, but they look like this...
eaca21e6-7285-49cf-9fc9-5f27ca665c39

This does not guarantee no naming conflict, but is likely to remain stable over time, is readable and easy to follow. Feel free to name your packages as you like. itu.madsh.myPackage org.madsh.otherPackage A package can be spread over more directories and jar files, as long they are all in the classpath.

In Java it is suggested to use a reverse DNS notation: dk.itu.courses.oop.2007.lesson3 Dont expect package names to translate into real world URL.
java.lang.util != http://util.lang.java

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

10

Inner classes
An inner class is used to describe a highly coupled to its outer class.
public class Line { private EndPoint p1, p2; public Line(Point start, Point end) { p1 = new EndPoint(start); p2 = new EndPoint(end); } public Point getStart() { return p1; } public Point getEnd() { return p2; } public String toString() { return "Line("+p1+","+p2+")"; } // Inner class private class EndPoint extends Point { private EndPoint(Point p) { super(p.getX(),p.getY()); } public void move(int dx, int dy) { p1.movePoint(dx,dy); p2.movePoint(dx,dy); } private void movePoint(int dx, int dy)
line point
dy dx dy dx

public class Point { private int x,y; public Point(int x, int y){ this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } public void move(int dx, int dy) { x += dx; y += dy; } public String toString(){ return "Point("+x+","+y+")"; } }

{ super.move(dx,dy); } } }

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

11

Inner objects and this


public class Line { private EndPoint p1, p2; private class EndPoint extends Point { public void move(int dx, int dy) { p1.movePoint(dx,dy); p2.movePoint(dx,dy); } // ... } // ... }

:EndPoint x:int y:int Line:Line.this :Line p1:EndPoint p2:EndPoint :EndPoint x:int y:int Line:Line.this

2 2

How does EndPoint refer to field p1 of Line? EndPoint instances has an implicit this reference in the same way as methods. It can be used explicitly as Line.this. p1 is equal to Line.this.p1

3 3

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

12

Flight example
On March 18th, SAS has a flight (SK0909) from Copenhagen til New York, Newark, scheduled to leave 12:05 and arrive 14:50. The list price for the cheapest ticket is DKK 3290 for a round trip. The airplane to be used is an Airbus 333. On April SK0909 is a return flight, which leaves Newark at 17:50 and arrives in Copenhagen the next morning 7:30. Problems: 18th,
public class BadFlight { public String flightNo; public String departing, arriving; public Date actualDeparting, actualArriving; public double monkeyClassPrice; public String planeType; // ... public BadFlight(...) { ... } // ... }

There is also a flight on March 19th. With many


of the same characteristics.

We need to register who is flying the plane. We need to register number of passengers. We need to register the actual arrival and
departure times.

public class ATC { public static void main(String[] args) { BadFlight sk0909 = new BadFlight( "SK0909", "CPH", "EWR", "March 18, 2004, 12:05 CET", "March 18, 2005, 14:05 EST", 3290, "Airbus 333" ); } }

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

13

Flight example, rewrite


public class FlightSchedule {

The problem with the flight class is common and known under the name itemdescriptor. The descriptor in this case is the general description of any SK0909, and the item is the SK0909 on the 18th March. A solution is shown to the right using a inner class. We assume that a Flight will not exists independent from a FlightSchedule.

public public public public public

final String flightNo; final String departing, arriving; String departureTime, arrivalTime; double monekyClassPrize; Airplane airplaneType;

public ArrayList<Flight> flights = new ArrayList<Flight>(); public FlightSchedule(String flightNo, String dep, String arr) { this.flightNo = flightNo; departing = dep; arriving = arr; } // ... class Flight { String departureDate; String actualDeparture, actualArrival; // ... Seat[] seats = new Seat[airplaneType.noSeats]; // ... class Seat {} }

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

14

Flight example
This is an example of hot to initialize a flight schedule and single flight...

class RealATC { public static void main(String[] args) { // Creating a FlightSchedule FlightSchedule sk0909 = new FlightSchedule("SK0909","CPH","EWR"); sk0909.departureTime = "12:05 CET"; sk0909.arrivalTime = "14:05 EST"; sk0909.airplaneType = Airplane.AIRBUS333; //Creating a Flight on a schedule FlightSchedule.Flight sk0909Feb1 = sk0909.new Flight(); sk0909Feb1.departureDate = "February 1, 2004"; sk0909.flights.add(sk0909Feb1); //When we are in the air sk0909Feb1.actualDeparture = "12:20 CET"; //Back on the ground sk0909Feb1.actualDeparture = "14:20 CET"; } }

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

15

Anonymous inner classes


It is possible to make inner objects which are instances of anonymous classes. Anonymous inner classes can be created inside methods and in connection with initializers.
Point flipPoint = new Point(3,4) { // overridding the move method public void move(int dx, int dy) { super.move(dy,dx); } };

Anonymous inner classes are mostly used in connection with event handling in Swing.

JButton button = new JButton("Press me!!!"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { //... } });

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

16

Declaring a parameter final


public Point uups(Point p){ return new Point(3,4) { public int getX(){ return p.getX(); } }; }
:Point :SomeClass::uups p:Point result:Point return:Point this:SomeClass <,> x:int y:int 6 6

If we try to compile the method above we get the following error:


local variable p is accessed from within inner class; needs to be declared final

:AnonymousPoint x:int 6 y:int 6 uups.this

Try to draw the method call and pay special attention to the this reference and references from the anonymous inner class to the outer...

from an inner class, you can only access local variables if they are declared final

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

17

Innerclases and local variables


public Point uups(final Point p){ return new Point(3,4) { public int getX(){ return p.getX(); } }; }
:Point :SomeClass::uups p:Point result:Point return:Point this:SomeClass <,> x:int y:int 6 6

Final means that the variable can never change. For inner classes this allows the compiler to create a copy of the local variable. Each local variable inside an inner class is copied to a field in the inner object. This makes it behaves as if the inner object is inner to the method call...

:AnonymousPoint x:int 6 y:int 6 p:Point

from an inner class, you can only access local variables if they are declared final

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

18

Inner classes and methods


One can extend an anonymous class with methods that are not present in the superclass. But one have not way to call the method from outside the anonymous class. The anonymous class has no name, so it is not possible to declare a variable of its type. The only way to reference the object is by one of the super classes types, and only members of that type is visible.
Point flipPoint = new Point(3,4) { // overridding the move method public void moveToZero() { super.move(-getX(),-getY()); } }; flipPoint.moveToZero(); // WRONG!

OOP E2007 Lesson 3 Encapsulation, packages and inner classes Mads Hjorth IT University Copenhagen

19

S-ar putea să vă placă și