46
3. Классы Программирование на Java Федор Лаврентьев МФТИ, 2016

Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Embed Size (px)

Citation preview

Page 1: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

3. КлассыПрограммирование на Java

Федор ЛаврентьевМФТИ, 2016

Page 2: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Пакеты (packages)

Page 3: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Файл java/lang/Integer.javapackage java.lang;

public class Integer { public static final int MAX_VALUE = ...; ...}

Page 4: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Файл ru/mipt/java/lection3/Example.javapackage ru.mipt.java.lection3;

[import java.lang.Integer;]import java.io.InputStream;import static java.lang.Integer.MAX_VALUE;import static java.lang.Integer.toHexString;

public class Example { Integer maxInt = MAX_VALUE; String maxString = toHexString(MAX_VALUE); InputStream is = new java.io.FileInputStream(“foo.txt”); InputSteam is2 = new ru.mipt.java.lection3. FileInputStream();}

Page 5: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Файлы и директорииru/\- mipt/ \- java/ |- lection3/ | |- Child.java | |- Example.java | \- Parent.java \- lection4/ \- Utility.javajava/|- io/| |- IOException.java| \- InputStream.java\- lang/ \- String.java

Page 6: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Прямое наследование

Page 7: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Наследованиеclass Rectangle { final double width, height; Rectangle(double width, double height) { this.width = width; this.height = height; }}

class Square extends Rectangle { Square(double side) { super(side, side); }}

Page 8: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

LSP (Barbara Liskov’s Substitution Principle)double calcArea(Rectangle r) { return r.getWidth() * r.getHeight();}

Rectangle a = new Rectangle(4, 5);calcArea(a); // 20

Rectangle b = new Square(4);calcArea(b); // 16

Square c = new Square(5);calcArea(c); // 25

Page 9: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Приведение и проверка типовpublic void draw(Shape shape) { if (shape instanceof Rectangle) { Rectangle rect = (Rectangle) shape; drawRectangle(rect);

} else if (shape instanceof Circle) { Circle circle = (Circle) shape; drawCircle(circle);

} else if (shape instanceof Line) { drawLine((Line) shape); }}

Page 10: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Абстрактные классыabstract class Shape { abstract double calcArea();}

class Rectangle extends Shape { ... @Override double calcArea() { return getWidth() * getHeight(); }}

Page 11: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Переопределение методаclass Object { public int hashCode() { ... }}

class Long [extends Object] { private final long value;

@Override public int hashCode() { return (int) (value ^ (value >>> 32)) }}

Page 12: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Вызов метода родительского классаclass Circle { public void draw() { Canvas.circle(x, y, radius); }}

class Sun extends Circle { @Override public void draw() { super.draw(); // Draw circle drawSunlight(); }}

Page 13: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Инстанцирование абстрактного классаShape a = new Rectangle(3, 4);a.calcArea(); // 12

Shape b = new Square(7);b.calcArea(); // 49

Shape c = new Shape();c.calcArea(); // ?

Page 14: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Инстанцирование абстрактного классаShape a = new Rectangle(3, 4);a.calcArea(); // 12

Shape b = new Square(7);b.calcArea(); // 49

Shape c = new Shape(); // WRONG!c.calcArea();

Page 15: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Анонимные классыShape a = new Rectangle(3, 4);a.calcArea(); // 12

Shape b = new Square(7);b.calcArea(); // 49

Shape c = new Shape() { double calcArea() { return 0; }}c.calcArea(); // 0

Page 16: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Модификаторы доступа

Page 17: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Инкапсуляция - private и publicpublic class Animal { private double x; private double y; private double bearing; public double getX() { return x; } public double getY() { return y; } public double getBearing() { return bearing; } public void rotate(double angle) { bearing = modulo(bearing + angle, 2 * Math.PI); }

public void stepUp(double distance) { x += distance * Math.cos(bearing); y += distance * Math.sin(bearing); }}

Page 18: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Точки расширения - protectedpublic class Animal { ... private boolean hungry; public boolean isHungry() { return hungry;} protected void setHungry(boolean hungry) { this.hungry = hungry; }}

public class LazyAnimal { @Override public void stepUp(double distance) { if (isHungry()) throw new IllegalStateException(); super.stepUp(distance); setHungry(true); }}

Page 19: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Доступ по умолчанию (package-local)package edu.phystech.java.lection3;

public class Animal { ... String name;}

public class Dog extends Animal { public String tellName() { return “Bark!”; }}

public class Student extends Animal { public String tellName() { return name; }}

public class Zookeeper { public String nameAnimal(Animal a) { return a.name; }}

Page 20: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Хорошая, годная инкапсуляцияpublic class Wallet { private double money = 0.0;

public void putMoney(double amount) { if (amount < 0) throw new IllegalArgumentException(); money += amount }

public void takeMoney(double amount) { if (amount < 0) throw new IllegalArgumentException(); if (amount > money) throw new IllegalArgumentException(); money -= amount; }

public double getMoney() { return money; }}

Page 21: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Нарушение инкапсуляцииpublic class Wallet { public double money = 0.0;

public void putMoney(double amount) { if (amount < 0) throw new IllegalArgumentException(); money += amount }

public void takeMoney(double amount) { if (amount < 0) throw new IllegalArgumentException(); if (amount > money) throw new IllegalArgumentException(); money -= amount; }

public double getMoney() { return money; }}

Page 22: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Public Morozoff в один ходpublic class Wallet { public double money; ...}

public static void leakMoney(Wallet w) { w.money = -5;}

Page 23: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Возможное нарушение инкапсуляцииpublic class Wallet { protected double money = 0.0;

public void putMoney(double amount) { if (amount < 0) throw new IllegalArgumentException(); money += amount }

public void takeMoney(double amount) { if (amount < 0) throw new IllegalArgumentException(); if (amount > money) throw new IllegalArgumentException(); money -= amount; }

public double getMoney() { return money; }}

Page 24: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Public Morozoff в два ходаpublic class Wallet { protected double money; ...}

pubic class LeakingWallet extends Wallet { public void setMoney(double amount) { money = amount; }}

public void leakMoney(LeakingWallet w) { w.setMoney(-5);}

Page 25: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Внутренние классыpublic class Dog { private double bearing; // Направление public class Head { private final int length; public String smash() {} }}

Page 26: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Вложенные классыpublic class Observable {

public static class Event { private final Observable source; private final String type; private final String cause; }

public static class Observer { void onEvent(Event e) { ... } }}

Page 27: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Множественное наследование

Page 28: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Интерфейсыpublic interface Planar { [public] void setLocation(Location l); [public] Location getLocation();}

public class Rectangle implements Planar { @Override void setLocation(Location l) { this.left = l.getX(); this.top = l.getY(); }

@Override void getLocation() { return new Location(getLeft(), getTop()); }}

Page 29: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Абстрактная имплементация интерфейсаpublic interface Planar { void setLocation(Location l); Location getLocation();}

public abstract class Shape implements Planar { // setLocation() unimplemented // getLocation() unimplemented}

public class Rectangle extends Shape { ...}

Page 30: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Наследование интерфейсовpublic interface Planar { void setLocation(Location l); Location getLocation();}

public interface Drawable extends Planar { void draw(Canvas c);}

public class Shape implements Drawable { ...}

Page 31: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Множественное наследованиеpublic class Geometry { ...}

public class Circle extends Geometry implements Drawable, Comparable, Closeable { ...}

Page 32: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Реализация по умолчаниюpublic interface Observable { List<Observer> getObservers(); void addObserver(Observer o) default { getObservers().add(o); }

Observer removeObserver(Observer o) default { getObservers().remove(o); }

void notifyObservers(Event e) default { List<Observer> observers = getObservers(); for (int i = 0; i <= observers.size(); ++i) { observers.get(i).onEvent(e); } }}

Page 33: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение объектов

Page 34: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение по ссылкеStudent s1 = new Student(“Vasya”, 21);Student s2 = new Student(“Vasya”, 21);Student s3 = s1;

assert s1 == s1; // trueassert s1 == s2; // falseassert s1 == s3; // true

Page 35: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение по ссылкеInteger a = 100500;Integer b = Integer.valueOf(100500);Integer c = Integer.valueOf(100500);

assert a == b;assert a == c;assert b == c;

Integer d = 42;Integer e = Integer.valueOf(42)

assert d == e;

Page 36: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение по ссылкеInteger a = 100500;Integer b = Integer.valueOf(100500);Integer c = Integer.valueOf(100500);

assert a == b; // WRONGassert a == c; // WRONGassert b == c; // WRONG

Integer d = 42;Integer e = Integer.valueOf(42)

assert d == e;

Page 37: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение по ссылкеInteger a = 100500;Integer b = Integer.valueOf(100500);Integer c = Integer.valueOf(100500);

assert a == b; // WRONGassert a == c; // WRONGassert b == c; // WRONG

Integer d = 42;Integer e = Integer.valueOf(42)

assert d == e; // CORRECT?!

Page 38: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение объектов – equalsclass Student { ... public boolean equals(Object o) { if (o == null) return false; if (this == o) return true; if (this.getClass() != o.getClass()) return false;

Student s = (Student) o; if (this.age != s.age) return false; if (this.name == null) return s.name == null; return this.name.equals(s.name); }}

Page 39: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение объектов – equals (в Java 7)class Student { ... public boolean equals(Object o) { if (o == null) return false; if (this == o) return true; if (this.getClass() != o.getClass()) return false;

Student s = (Student) o; if (this.age != s.age) return false;

return Objects.equals(this.name, s.name); }}

Page 40: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение объектов – хеш-кодclass Student { ... public int hashCode() { final int prime = 37; return age * prime + name.hashCode(); } }

Page 41: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Сравнение объектов – по умолчаниюpublic class Object { ... public native int hashCode(); // адрес в памяти

public boolean equals(Object o) { return this == o; }}

Page 42: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Контракт на сравнение объектов• a.equals(a) == true; // Рефлексивность• a.equals(b) == b.equals(a); // Симметричность• a.equals(b) && b.equals(c) => a.equals(c); // Транзитивность• a.equals(b) == a.equals(b); //Консистентность• a.hashCode() == a.hashCode(); //Консистентность• a.equals(b) == true => a.hashCode() == b.hashCode();• a.equals(null) == false;

Page 43: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Enum

Page 44: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Enumpublic enum TaskState { QUEUED, RUNNING, FINISHED, FAILED;}

import static TaskState.*;

public class Task { private TaskState state;

void updateState(TaskState nextState) { if (state == FINISHED || state == FAILED) { throw new IllegalStateException(); } if (state == RUNNING && nextState == QUEUED) { throw new IllegalStateException(); } state = nextState; }}

Page 45: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Расширение enumpublic enum TaskState { QUEUED(0), RUNNING(1), FINISHED(2), FAILED(2);

private final int order;

private TaskState(int order) { this.order = order; }

public boolean isUpdateAllowed(TaskState next) { return next.order > this.order; }}

Page 46: Programming Java - Lection 03 - Classes - Lavrentyev Fedor

Расширение enumimport static TaskState.*;

public class Task { private TaskState state;

void updateState(TaskState nextState) { if (!state.isUpdateAllowed(nextState) { throw new IllegalStateException(); } state = nextState; }}