[ Коллок по JAVA ]
1) Какие средства Java поддерживают принцип абстракции?
-Абстрактный класс
-Интерфейс
-Абстрактный метод
-Generic
2) Какие средства Java обеспечивают поддержку ИНКАПСУЛЯЦИИ. Расположите их в порядке открытости.
Модификаторы доступа:
Применимо к классам:
public – класс доступен извне пакета.
Для вложенных(внутренних) классов дополнительно действуют следующие модификаторы:
protected – к классу имеют доступ только классы наследники объемлющего класса или классы в том же пакете
private – к классу имеет доступ только объемлющий класс
Применимо к полям и методам (членам класса):
private - члены класса доступны только внутри класса
package-private или default (по умолчанию) - члены класса видны внутри пакета
protected - члены класса доступны внутри пакета и в классах-наследниках
public - члены класса доступны всем
3) Определите понятие объекта. Перечислите варианты отношений между объектами, в чем зависимость состояния и поведения объекта?
Объекты - экземпляры классов (class instance) и массивы(По Рылову)
Объект - сущность, обладающая поведением, состоянием и идентичностью (уникальностью) (ООП)
Отношение между объектами: зависимость, ассоциация, агрегация, композиция. Поведение может определять и изменять состояние объекта, изменяя некоторые его поля.
4) Определите понятие класса. Перечислите варианты отношения между классами. Обозначьте взаимосвязь между этими отношениями, если она существует.
Класс - модель, описывающая сущность, он же шаблон, "чертёж", по которому будет строится объект. Отношения: зависимость, ассоциация, агрегация, композиция. Композиция частный случай агрегации, агрегация частный случай ассоциации. Наиболее сильным является композиция.
НАПоМиНАЛКА:
Ассоциация означает, что объекты двух классов могут ссылаться один на другой, иметь некоторую связь между друг другом. Например Менеджер может выписать Счет. Соответственно возникает ассоциация между Менеджером и Счетом. Еще пример - Преподаватель и Студент - т.е. какой-то Студент учится у какого-то Преподавателя. Ассоциация и есть описание связи между двумя объектами. Студент учится у Преподавателя. Идея достаточно простая – два объекта могут быть связаны между собой и это надо как-то описать.
Агрегация - отношение когда один объект является частью другого. Например Студент входит в Группу любителей физики.
Композиция - еще более “жесткое отношение, когда объект не только является частью другого объекта, но и вообще не может принадлежат еще кому-то. Например Машина и Двигатель. Хотя двигатель может быть и без машины, но он вряд ли сможет быть в двух или трех машинах одновременно. В отличии от студента, который может входить и в другие группы тоже. Такие описания всегда несколько условны, но тем не менее.
5) Принцип подстановки Лисковой
Наследующий класс должен дополнять, а не замещать поведение базового класса.
Если у нас есть класс A (не виртуальный, а вполне реально используемый в коде) и отнаследованный от него класс B, то если мы заменим все использования класса A на B, ничего не должно измениться в работе программы. Ведь класс B всего лишь расширяет функционал класса A.
6) В чём состоит поддержка принципа типизации в Java? Приведите пример кода безопасного приведения типов.
Типизация –это способ защититься от использования объектов одного класса вместо другого, или по крайней мере управлять таким использованием
- На стадии компиляции происходит проверка соответствия типов
- Язык предоставляет средства динамической проверки (например instanceof - определяет, является ли объект экземпляром заданного типа)
При вычислении выражений аргументы оператора приводятся к одному типу, при этом более простой тип приводится к более сложному путем продвижения (byte-> short -> int ->long; float -> double; int->float или double):
short c = 456;
double d = 3.f / 2 + (c + 100000);
-----------------------------------------------------------------------------------------
Правила кастинга такие(поддержка принципа типизации, видимо?):
Downcasting - нисходящее приведение, то есть приведение от предка к потомку предку подтипу возможно если только исходная переменная является подтипом приводимого типа. Ошибка может возникать runtime или на этапе компиляции. Скажем:
Object object;
String s=(String )object; //разрешено, поскольку тип переменной object
//может быть String'ом, но это выяснится только в runtime
Double object=new Double(1.0);
String s=(String )object; //ошибка будет на этапе компиляции поскольку тип
// object известен компилятору и он не приводим к типу String
Object object=new Double(1.0);
Number n=(Number )object; //разрешено, поскольку Double
// является подтипом Number
Upcasting - восходящее приведение типов или приведение типов от потомка к предку, разрешено всегда.
безопасные преобразования, например от int к double или от сына к родителю называют расширяющими, т.е мы даем типу данных с более низкими возможностями расширится, например целому типу данных, даем возможность становится вещественным, расширяя его область применения. Преобразование называется расширяющим, если тип данных к которому мы приводим включает в себя тип данных который мы хотим привести для базовых типов.
Сужающие преобразования всегда связаны с некоторой потерей информации, например преобразовывая от double к int мы теряем все значения после запятой, что вызывает опасения у компьютера и только явное указание типа данных может уверить его, что мы делаем это преобразование в здравом уме и твердой памяти.
Пример:
public class Shape {
}
public class Square extends Shape {
}
Square square;
Shape shape = square;//расширяющие преобразование
square = shape;//сужающие преобразование
утиная типизация
Если что-то ходит как утка, и крякает как утка, то будем относиться к этому как к утке.
public interface IQuackable {
void quack();
}
void quack();
}
public class Duck {
public void quack () {
System.out.println(“I am a Duck!”);
}
}
public class Frog {
public void quack () {
System.out.println(“I am a Frog!”);
}
}
public void quack () {
System.out.println(“I am a Duck!”);
}
}
public class Frog {
public void quack () {
System.out.println(“I am a Frog!”);
}
}
// ...
IQuackable[] quakers = new IQuackable[] {
Cast(IQuackable.class, new Duck()),
Cast(IQuackable.class, new Frog())
};
for(IQuackable q : quakers) {
q.quack();
}
// …
IQuackable[] quakers = new IQuackable[] {
Cast(IQuackable.class, new Duck()),
Cast(IQuackable.class, new Frog())
};
for(IQuackable q : quakers) {
q.quack();
}
// …
7) Перечислите примитивные типы языка Java, которые вы знаете. Каков их диапазон допустимых значений?
Тип
|
Длина (в байтах)
|
Диапазон или набор значений
|
boolean
|
Размер зависит от настроек виртуальной машины Java
|
true, false
|
byte
|
1
|
−128..127
|
char
|
2
|
0..216−1, или 0..65535
|
short
|
2
|
−215..215−1, или −32768..32767
|
int
|
4
|
−231..231−1, или −2147483648..2147483647
|
long
|
8
|
−263..263−1, или примерно −9.2·1018..9.2·1018
|
float
|
4
|
-(2-2−23)·2127..(2-2−23)·2127, или примерно −3.4·1038..3.4·1038, а также
|
double
|
8
|
-(2-2−52)·21023..(2-2−52)·21023, или примерно −1.8·10308..1.8·10308, а также
|
8) Для чего нужен класс java.lang.Class. Как узнать класс объекта?
Класс Class является метаклассом (класс, экземпляры которого в свою очередь являются классами) для всех классов Java.
Когда JVM загружает файл .class, который описывает некоторый тип, в памяти создается объект класса Class, который будет хранить это описание.
Нужен для:
- Для рефлексии. Рефлексия - это механизм исследования данных о программе во время её выполнения.
- Если у нас есть экземпляр Class, мы можем получить всевозможную информацию об этом классе и даже осуществлять операции над ним.
Получение объекта типа Class
MyClass a = new MyClass();
Class aclass = a.getClass();
String className = aclass.getName();
--------------------------------------------------------------------------------------------------------------------------
Самое простое, что обычно делается в динамическом программировании, - это получают объект типа java.lang.Class. Если у нас есть экземпляр объекта Class мы можем получить всевозможную информацию об этом классе и даже осуществлять операции над ним. Вышеприведенный метод getClass() часто полезен тогда когда есть экземпляр объекта, но не известно какого класса этот экземпляр.
9) Какие строки содержат ошибку и почему?
Ответ:
a. int[] a = new int[4]; - все ОК
b. int[] a = new int[]; - нельзя инициализировать массив пустой длины.
c. int[4] a = new int[4]; - синтаксическая ошибка, так как int[4] в первом случае является типом переменной.
d. int a[] = new int[4] - все ОК;
10) Какие строки содержат ошибку и почему?
Ответ:
a. final class A{...} - все ОК
b. abstract class A{...} - все ОК
c. protected class A{...} - Если внутри другого класса, то ОК
d. abstract int b; - поля не могут быть абстрактными.
e. protected int b(3); - так не инициализируется
11) Какой блок catch будет ловить все?
a. catch(Error e) {}
b. catch(AbstractException e) {}
c. catch(Throwable e) {} - ответ (т.к. Exception и Error от него наследуются)
d. catch(Exception e) {}
12) Вы имеете иерахию типов и объект класса С с = new С();
Как вызвать B.f() из метода С.f()?
Как вызвать B.f() из метода С.f()?
class A{
public void f(){}
}
class B extends A{
public void f(){}
}
class C extends B{
public void f(){}
}
Ответ: super.f(); в тело C::f();
Как вызвать A.f() из метода С.f()?
Ответ: напрямую никак
13)Как правильно создать экземпляр класса Inner, принадлежащий классу Outer в методе main();
class Outer {
class Inner {
}
}
public class Main {
public static void main(String argv[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // Эти 2 строчки и есть ответ :)
}
}
14) Что выведет на экран данная программа:
public class A {
public void method() throws Exception {
System.out.println("Шаг 2");
throw new Error("Ошибка");
}
public static void main(String[] args) {
A a = new A();
System.out.println("Шаг 1");
try {
a.method();
} catch (Exception ex) {
System.out.println("Исключение!");
}
System.out.println("Шаг 3");
}
}
вывод:
Шаг 1
Шаг 2
Exception in thread "main" java.lang.Error: Ошибка
at Main.method(Main.java:6)
at Main.main(Main.java:12)
Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует пытаться обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM.(собственно поэтому после того как кинули Error все завершилось)
15) Что выведет на экран данная программа:
public class A {
public static void add3(Integer i) {
int val = i.intValue();
val += 3;
i = new Integer(val); //создаём новый объект, теперь i ссылается на него
}
public static void main(String[] args) {
Integer i = new Integer(0);
add3(i);
System.out.println(i.intValue()); //значит тут выведется 0
}
}
16) Какое из следующих определений запрещает наследование класса FooBar?
a. static class FooBar():
b. private class FooBar():
c. abstract class FooBar():
Ответ: d. final class FooBar():
e. final abstract class FooBar():
17) Какое утверждение является верным:
a. Анонимный класс может быть объявлен статическим.
(НЕВЕРНО: Поскольку анонимный класс не содержит как такового объявления, его нельзя объявить статическим.)
b. Статический внутренний класс не может быть статическим членом внешнего класса.
(может, походу)
c. Статический внутренний класс не требует экземпляр объемлющего класса.
(да!!!)
class FooBar {
static class near {
public static void f() {
System.out.println("!!!!!");
}
}
}
public class Main {
public static void main(String[] args) {
FooBar.near n = new FooBar.near();
}
}
d. На переменные экземпляра внутреннего статического класса можно ссылаться, используя имя этого класса.
(нет, переменные у каждого экземпляра свои, и имя класса нам ничего не даст, нужно именно имя объекта)
e. Для создания экземпляра статического внутреннего класса требуется экземпляр внешнего класса.
(нет. смотри пункт С)
18) Напишите цикл, который подсчитает среднее значение объектов-значений, хранящихся в Map.
class EmptyMapException extends Exception {}
class Sredn {
public int caclSredn(Map<String, Integer> m) throws EmptyMapException {
if(0 == m.size()) {
throw new EmptyMapException();
}
int sum = 0;
for(Map.Entry<String, Integer> ent: m.entrySet()){
sum += ent.getValue();
}
return sum/m.size();
}
}
public class Main {
public static void main(String[] args) {
Sredn sr = new Sredn();
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("1", 1);
map.put("2", 10);
try {
System.out.println(sr.caclSredn(map));
} catch(EmptyMapException e) {
System.out.println("Map is empty!");
}
}
}
Мой:
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map <String, Integer> map = new HashMap<String, Integer>();
map.put("1", 1);
map.put("2", 2);
int sum = 0;
for (Object obj: map.keySet()){
sum += map.get(obj);
}
System.out.println(((float)sum / (float)map.size()));;
}
}
19) Метод быстрого копирования.
Ответ:
class Copy {
public void copyStreams(InputStream in, OutputStream out){
byte[] buffer = new byte[256];
while(true) {
int read = 0;
try {
read = in.read(buffer);
if(1 >= read) { //becose we read '\n'
break;
}
} catch(IOException e) {
System.out.println("Error reading from stream!");
break;
}
try {
out.write(buffer, 0 ,read);
} catch(IOException e) {
System.out.println("Error writing to stream!");
break;
}
}
}
}
public class Main {
public static void main(String[] args) {
Copy copy = new Copy();
copy.copyStreams(System.in, System.out);
}
}