QA And Automation - Intro To Java

Part 2

4x Java

  • Базови конструкции в езика. Класове, обекти и интерфейси.

  • Object Equality. Интерфейси и Полиморфизъм.

  • Наследяване, Абстрактни класове и полиморфизъм.

  • Изключения и JUnit

Въпроси за загрявка

Какво представлява един клас?

Рецепта за обекти. Дефинира атрибути и методи

Въпроси за загрявка

Какво представлява един обект?

Инстанция на клас с конкретни данни.

Въпроси за загрявка

Какво има един обект?

State (състояния) +

Behaviour (поведение)

Въпроси за загрявка

Кое определя състоянието на един обект?

Стойността на неговите атрибути.

Въпроси за загрявка

Как може да променим състоянието на един обект?

  1. Като променяме директно публично-достъпните атрибути
  2. Чрез неговите методи (най-често void)

Въпроси за загрявка

Как създаваме нов обект от клас?

Чрез ключовата дума  new

Въпроси за загрявка

Какво представлява конструктор методът?

Първият метод, ако го има, който се извиква при създаване на нов обект от клас.

Въпроси за загрявка

Колко конструктора може да има един клас?

Повече от един.

Въпроси за загрявка

Как може да извикаме даден конструктор от друг конструктор в един клас?

чрез this(arguments)

Въпроси за загрявка

Какво е this?

Вътрешна референция към конкретният обект, върху който се вика даден метод.

Дефиниция: Сигнатура на метод

Сигнатурата на един метод представлява неговото име + броят и типовете на неговите аргументи.

 Сигнатура на метод

public void doSomething(String a, String b) {}
doSomething(String, String)

 Сигнатура на метод

public double calc(double a, int b, boolean c) {}
calc(double, int, boolean)

Method Overloading

  • В Java може да дефинираме един метод няколко пъти, стига той да има различна сигнатура

  • Наличието на повече от 1 конструктор е вид method overloading.

Method Overloading

public class Panda {
  public void eat(Bamboo bamboo) {}
  public void eat(Bamboo bamboo, int count) {}
  public void eat(ArrayList<Bamboo> bamboos) {}

}

Kакви са сигнатурите?

eat(Bamboo)
eat(Bamboo, int)
eat(ArrayList<Bamboo>)

Това възможно ли е?

public class Person {
  public void greet(String firstName,
                    String lastName) {}
  public void greet(String lastName,
                    String firstName) {}

}

Какви са сигнатурите?

greet(String, String)
greet(String, String)

Този method overloading не е възможен.

assertEquals(double expected, double actual)
assertEquals(String expected, String actual)
assertEquals(int expected, int actual)
...

Koга два обекта са еднакви?

Когато са еднакви?

Koга два обекта са еднакви?

  • Еднаквостта я определяме ние. Критерият зависи от нас.

  • == между два обекта ще сравни тяхната референция. Това не ни върши работа.

Koга два обекта са еднакви?

p1 = new Person("Ivaylo");
p2 = new Person("Ivaylo");

System.out.print(p1 == p2);
false

Koга два обекта са еднакви?

System.out.print(p1 == p2);
  • Две референции винаги са различни, освен ако не са една и съща референция*

  • * при String има няколко corner case-a.

Примитивните типове са OK при ==

System.out.print(1 == 1); // true

Обекти се сравняват чрез метод. Това е equals

System.out.println(p1.equals(p2));

Object Equality

  • Това е наша задача. Ние трябва да дефинираме public boolean equals(Object other) {}
  • Този метод трябва да каже кога два обекта са еднакви.
  • При p1.equals(p2) имаме
    • p1 == this
    • p2 == other
  • Хайде да го видим!

Object Equality

public class Panda {
  public String name;

  public boolean equals(Object obj) {
    if(!(obj instanceof Panda)) {
      return false;
    }

    Panda other = (Panda) obj;

    return this.name.equals(obj.name);
  }

Wait, what?

  1. Защо получаваме Object, а не Panda?
  2. Какво е instanceof?
  3. Какво е Panda other = (Panda) obj?
  1. Викат му наследяване. Повече следващият път.
  2. Оператор, който проверява дали обект е инстанция на даден клас. Връща true / false
  3. Нарича се cast-ване. Ако е Panda, правим я Panda.

Eclipse генерира equals.

@Override
public boolean equals(Object obj) {
  if (this == obj) {
    return true;
  }
  if (obj == null) {
    return false;
  }
  if (!(obj instanceof Panda)) {
    return false;
  }
  Panda other = (Panda) obj;
    if (name == null) {
       if (other.name != null) {
         return false;
       }
    } else if (!name.equals(other.name)) {
      return false;
    }
    return true;
}

Задача за следващият път:

Ако obj1.equals(obj2), то obj1.hashCode() == obj2.hashCode()

Някой от вас ще трябва да обясни защо?

Ние създаваме и тестваме системи.

Когато искаме да тестваме публичната част, гледаме какъв е интерфейсът.

Интерфейсът задава очаквано поведение.

  1. Ако знаем поведението, не ни интересува имплементацията.
  2. Ние тестваме по очакваното поведение.
  3. Имплементацията остава скрита за нас.

Пример: Кеширане

Пример: Кеширане

  1. Искам да мога да запазя стойност в даден cache.

  2. Искам да мога да проверя дали стойност се намира в кеш

  3. Искам да мога да взема стойност от кеш

Пример: Кеширане

// Псевдо Java
interface Cache {
    add(key, value)
    get(key)
    hasValue(key)
}

Cache c = new SomeKindOfCacheImplementation();

c.add('one', 1)
assert c.hasValue('one')
assert c.get('one') == 1
assert c.get('two') == some empty value

Пример: Кеширане

// истинска Java
public interface Cache {
    public void add(String key, Object value);
    public Object get(String key);
    public boolean hasValue(String key);
}

Пример: Кеширане

  1. Интересуваме се от interface-a

  2. Кешът може да го пазим в паметта.

  3. Кешът може да го пазим във файлове

  4. Кешът може да го пазим в база от данни

  5. Кешът може да го пазим в key-value store

Interface в Java

  • Дефинира задължително-присъстващи методи.

  • Не може да вдигнете инстанция на interface-a.

  • Трябва да бъде имплементиран от клас

Имплементация

public class MemoryCache implements Cache {
    private HashMap<String, Object> cache = new HashMap<>();
    
    public void add(String key, Object value) {
      cache.put(key, value);
    }

    public Object get(String key) {
      return cache.get(key); // returns null if not present
    }

    public boolean hasValue(String key) {
      return cache.containsKey(key);
    }
}

Използване

public static void main(String[] args) {
  Cache c = new MemoryCache();
}
Cache c = new MemoryCache();

Тип име = new Имплементация();

Тип име = new Имплементация();

  1. Ако Тип съвпада с Имплементация, всичко е наред.

  2. Ако не съвпадат?

  3. String a = new ArrayList<Panda>(); ?

ПО

ЛИ

ЦАЙ?

ПО

ЛИ

МОРФИЗЪМ

Полиморфизъм

Типът може да е по-общ от имплементацията.

Interface-ът създава нов тип.

A a = new B();

  1. A e интерфейс, който B имплементира

  2. A е клас, който B наследява.

  3. A-то дава множеството на публичните методи

  4. B дава тяхната имплементация

Ето за това го правим

Cache c = ApplicationSettings.getDefaultCache();
  1. Не знаем какъв конкретен Cache ползваме.

  2. Но знаем как да го използваме, защото му знаем интерфейса.

QA And Automation - Intro to Java - Part 2

By Hack Bulgaria

QA And Automation - Intro to Java - Part 2

  • 1,543