Главная страница

Новый документ (1). Концепция оопобъектноориентированноепрограммирование


Скачать 469.07 Kb.
НазваниеКонцепция оопобъектноориентированноепрограммирование
Дата27.09.2022
Размер469.07 Kb.
Формат файлаpdf
Имя файлаНовый документ (1).pdf
ТипДокументы
#700569
страница2 из 4
1   2   3   4
7
public class Circle implements Shape {
private String name;
private Double area;
private String perimeter;
}
4. Как правильно организовать доступ к полям класса?
Модификатор доступа — private. Доступ через методы get\set.
5. Дайте определение понятию “конструктор”.
Конструктор — это специальный метод, который вызывается при создании нового объекта.
Конструктор инициализирует объект непосредственно во время создания. Имя конструктора совпадает с именем класса, включая регистр, а по синтаксису конструктор похож на метод без возвращаемого значения.

1
2
3
4
5
public class Circle implements Shape {
public Circle() {
}
}
6. Чем отличаются конструкторы по умолчанию, копирования и конструктор с параметрами?
Конструктор по умолчанию не принимает никаких параметров. Конструктор копирования принимает в качестве параметра объект класса. Конструктор с параметрами принимает на вход параметры (обычно необходимые для инициализации полей класса).
1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
//конструктор по умолчанию
public Circle() {
}
//конструктор копирования
public Circle(Circle circle) {
this(circle.getName(),
circle.getArea(),
circle.getPerimeter()); //будет вызван конструктор с параметрами
ниже
}
//конструктор с параметрами
public Circle(String name, Double area, String perimeter) {
this.name = name;
this.area = area;
this.perimeter = perimeter;
}
Обращаю внимание, что тема копирования (clone()) достаточно глубокая с
возможностью возникновения множества неявных проблем. Немного можно почитать

здесь http://habrahabr.ru/post/246993/.
7. Какие модификации уровня доступа вы знаете, расскажите про каждый из них.
● private (закрытый) — доступ к члену класса не предоставляется никому, кроме
методов этого класса. Другие классы того же пакета также не могут обращаться
к private-членам.
● default, package, friendly, доступ по умолчанию, когда никакой модификатор не
присутствует — член класса считается открытым внутри своего собственного
пакета, но не доступен для кода, расположенного вне этого пакета.Т.е. если
package2.Class2
extends
package1.MainClass
, то в
Class2
методы без идентификатора
из
MainClass
видны не будут.
● protected (защищённый) — доступ в пределах пакета и классов наследников.
Доступ в классе из другого пакета будет к методам public и protected главного
класса. Т.е. если
package2.Class2
extends
package1.MainClass
, то внутри
package2.Class2
методы с идентификатором
protected
из
MainClass
будут видны.
● public (открытый) — доступ для всех из любого другого кода проекта
Модификаторы в списке расположены по возрастающей видимости в программе.
8.
Расскажите об особенностях класса с единственным закрытым (private)
конструктором.
Невозможно создать объект класса у которого единственный private конструктор за
пределами класса. Поэтому нельзя унаследоваться от такого класса. При попытке
унаследоваться будет выдаваться ошибка:
There is no default constructor available in
имяКласса
. А при попытке создать объект этого класса:
ИмяКласса() has private access in
ИмяКласса
9. О чем говорят ключевые слова “this”, “super”, где и как их можно использовать?
super — используется для обращения к базовому классу, а this к текущему. Пример:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Animal {
public void eat() {
System.out.println("animal eat");
}
}
public class Dog extends Animal {
public void eat() {
System.out.println("Dog eat");
}
public void thisEat() {
System.out.println("Call Dog.eat()");
this.eat();
}
public void superEat() {
System.out.println("Call Animal.eat()");
super.eat();
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.thisEat();
dog.superEat();
}

33
34
35
36
37
38
}
Dog eat
Call Dog.eat()
Dog eat
Call Animal.eat()
animal eat
Если написать super(), то будет вызван конструктор базового класса, а если this(), то
конструктор текущего класса. Это можно использовать, например, при вызове
конструктора с параметрами:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public Dog() {
System.out.println("Call empty constructor");
}
public Dog(String name) {
System.out.println("Call constructor with Name");
this.name = name;
}
public Dog(String name, Double weight) {
this(name);
this.weight = weight;
System.out.println("Call constructor with Name and
Weight");
}
}
..
public static void main(String[] args) {
Dog dog1 = new Dog("name", 25.0);
}
//Вывод
Call constructor with Name

23 Call constructor with Name and Weight
10. Дайте определение понятию “метод”.
Метод — это последовательность команд, которые вызываются по определенному имени.
Можно сказать что это функция и процедура (в случае void метода).
11. Что такое сигнатура метода?
Сигнатура метода в Java — это имя метода плюс параметры (причем порядок параметров имеет значение).
В сигнатуру метода не входит возвращаемое значение, бросаемые им исключения, а также модификаторы.
Ключевые слова public, protected, private, abstract, static, final, synchronized, native, strictfp в т.ч.
аннотации для метода — это модификаторы и не являются частью сигнатуры.
http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.2 12. Какие методы называются перегруженными?
Java позволяет создавать несколько методов с одинаковыми именами, но разными параметрами. Создание метода с тем же именем, но с другим набором параметров называется перегрузкой. Какой из перегруженных методов должен выполняться при вызове,
Java определяет на основе фактических параметров.
1
2
3
4
5
public void method() { }
public void method(int a) { }
public void method(String str) { }
13. Могут ли нестатические методы перегрузить статические?
Да. Это будут просто два разных метода для программы. Статический будет доступен по
имени класса.
14. Расскажите про переопределение методов. Могут ли быть переопределены статические методы?
Метод в классе-наследнике, совпадающий по сигнатуре с методом из родительского класса называется переопределенным методом. Переопределить базовый статический метод нельзя:
Instance method имяМетода in классНаследник cannot override method имяМетода
in родительскийКласс
15. Может ли метод принимать разное количество параметров (аргументы переменной длины)?
Да. Запись имеет вид
method(type … val)
. Например
public void method(String … strings)
, где
strings
это массив, т.е. можно записать
1
2
3
4
5
public void method (String ... strings) {
for (String s : strings) {
}
}
16. Можно ли сузить уровень доступа/тип возвращаемого значения при переопределении метода?
При переопределении метода нельзя сузить модификатор доступа к методу (например с public в MainClass до private в Class extends MainClass). Изменить тип возвращаемого значения при переопределении метода нельзя, будет ошибка
attempting to use incompatible return type.
Но можно сузить возвращаемое значение, если они совместимы. Например:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Animal {
public Animal eat() {
System.out.println("animal eat");
return null;
}
public Long calc() {
return null;
}
}
public class Dog extends Animal {
public Dog eat() {
return new Dog();
}
/*attempting to use incompatible return type
public Integer calc() {
return null;
}
*/
}
17. Как получить доступ к переопределенным методам родительского класса?
super.method();
18. Какие преобразования называются нисходящими и восходящими?
Преобразование от потомка к предку называется восходящим, от предка к потомку —
нисходящим. Нисходящее преобразование должно указываться явно с помощью указания нового типа в скобках.

Например:
1
2
3
4
Animal dog = new Dog(); //восходящее преобразование. Будет потерян
доступ ко всем методам, которые есть только у класса Dog.
int x = 100;
byte y = (byte) x;
//нисходящее преобразование. Должно быть
указано явно
19. Чем отличается переопределение от перегрузки?
Переопределение используется тогда, когда вы переписываете (переделываете,
переопределяете) УЖЕ существующий метод. Перегрузка — это использование одного имени, но с разными входными параметрами. Например нам нужно, чтобы метод toString()
для нашего класса выдавал какой-то осмысленный текст. Тогда мы переопределяем метод из класса Object и реализуем этот метод так, как нам это нужно.
1
2
3
4
@Override
public String toString() {
return "Хочу чтобы писался текст, а не название класса@2234SD!"
}
Тогда как перегрузка обычно используется, чтобы не придумывать каждый раз новое
имя, когда методы отличаются только входными параметрами. При перегрузке
необходимый метод определяется на этапе компиляции на основе сигнатуры
вызываемого метода, тогда как при переопределении нужный метод будет выявлен
во время выполнения исходя из реального типа объекта.
20. Где можно инициализировать статические/нестатические поля?
Статические поля можно инициализировать при объявлении, в статическом или
динамическом блоке инициализации. Нестатические поля можно инициализировать
при объявлении, в динамическом блоке инициализации или в конструкторе
21. Зачем нужен оператор instanceof?

Оператор instanceof возвращает true, если объект является экземпляром класса или
его потомком.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MainClass {
public static void main(String[] a) {
String s = "Hello";
int i = 0;
String g;
if (s instanceof java.lang.String) {
// попадем сюда, т.к. выражение будет true
System.out.println("s is a String");
}
if (i instanceof Integer) {
// это отобразится, т.к. будет использована автоупаковка
(int -> Integer)
System.out.println("i is an Integer");
}
if (g instanceof java.lang.String) {
// g не инициализирована и поэтому сюда мы не попадем, т.к.
// g - null и instanceof вернет false для null.
System.out.println("g is a String");
}

20 }
22. Зачем нужны и какие бывают блоки инициализации?
Блоки инициализации представляют собой наборы выражений инициализации
полей, заключенные в фигурные скобки и размещаемые внутри класса вне
объявлений методов или конструкторов. Блок инициализации выполняется так же,
как если бы он был расположен в верхней части тела любого конструктора. Если
блоков инициализации несколько, они выполняются в порядке следования в тексте
класса. Блок инициализации способен генерировать исключения, если их
объявления перечислены в предложениях throws всех конструкторов класса.
Бывают статические и нестатические блоки инициализации. Также возможно создать
такой блок в анонимном классе.
1
2
3
4
5
6
7
8
9
10
11
class Foo {
static List abc;
static {
abc = new LinkedList();
for (char c = 'A'; c <= 'Z'; ++c) {
abc.add( c );
}
}
}
//Пример нестатического блока инициализации
class Bar {

12
13
14
15
16
17
18
19
20
21
22
23
24
{
System.out.println("Bar: новый экземпляр");
}
}
//Пример инициализации в анонимном классе
JFrame frame = new JFrame() {{
add(new JPanel() {{
add(new JLabel("Хабрахабр?") {{
setBackground(Color.BLACK);
setForeground(Color.WHITE);
}});
}});
}};
23. Каков порядок вызова конструкторов и блоков инициализации двух классов: потомка и его предка?
Сначала вызываются все статические блоки от первого предка до последнего
наследника. Потом попарно вызываются динамический блок инициализации и
конструктор в той же последовательности (от предка до последнего потомка).
Хорошая картинка, демонстрирующая что происходит на самом деле при
инициализации с ресурса javarush.ru:

Вот простенький пример, который это демонстрирует:

1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
public class Pet {
private String name;
static {
System.out.println("Static block in Pet");
}
{
System.out.println("First block in Pet");
}
{
System.out.println("Second block in Pet");
}
public Pet() {
System.out.println("Pet empty constructor");
}
public Pet(String name) {
System.out.println("Pet constructor with Name " + name);
this.name = name;
}
}

7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
public class Cat extends Pet {
private String name;
static {
System.out.println("Static block in Cat");
}
{
System.out.println("First block in Cat");
}
{
System.out.println("Second block in Cat");
}
public Cat() {
System.out.println("Cat empty constructor");
}
public Cat(String name) {
super(name); // without this will call super(). Если эту
строчку убрать, то будет вызван конструктор Pet();
System.out.println("Cat constructor with Name: " + name);

3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0
4
1
4
this.name = name;
}
}
public class TestInitOrder {
public static void main(String[] args) {
Cat cat = new Cat("Rizhick");
}
}
//Вывод
Static block in Pet
Static block in Cat
First block in Pet
Second block in Pet
Pet constructor with Name Rizhick
First block in Cat
Second block in Cat
Cat constructor with Name: Rizhick

2
4
1   2   3   4


написать администратору сайта