2016-09-02 4 views
2

мы можем достичь выхода двух способов один является типажами и один без типажейЧто такое использование типажей в Java

A a=new B() // without typecaste 

A a = (A)a// with Typecaste 

в обоих направлениях, мы получаем то же output.so, что использование типажей

+1

Какой выход вы имеете в виду? – xenteros

ответ

1

Предположим, что у вас есть список Animal s. и у вас есть Tiger s и Lion s в нем.

ArrayList<Animal> animals = new ArrayList<>(); 
//add some Tigers and some Lions 
//sort so Tigers are at the beggining of the list 
Tiger t = (Tiger)animals.get(0); 

Без кастинга вы получите макет типа missmatch во время компиляции. С броском вы рискуете только ClassCastException, который можно легко поймать с помощью try-catch

Это просто пример правильного использования класса в Java.

0

Кастинг предназначен для «противоположного направления», то есть для преобразования в выражение подтипа исходного выражения.

Пример

Учитывая

Object o = "Hello World"; 
String s = o; 

не компилируется, но

String s = (String) o; 

компилирует. Это может дать, например, ClassCastException. если Integer хранился в o.

0
A a = new B(); 

будет работает только если B наследоваться от A.

Если B наследует от A, типа бросок не требуется, поскольку B является A. Тип литой будет необходим, если вам нужно набрать актерский к подклассу:

A a = new B(); 
B b = (B) a; 

Хотя это было бы незаконным:

A a = new A(); 
B b = (B) a; 

, как a не B.

-2
A a=new B() 

применима только тогда, когда class B распространяется class A. Таким образом, дополнительные методы, доступные в class B, кроме class A, будут доступны с reference a.

Когда вы сделаете это

A a = (A)a 

Тогда на самом деле вы вниз заливки объекта class B в объект class A. И это правда, что дочерний объект может быть введен в качестве родителя.После этого оператора reference a не сможет позвонить по любому методу class B, который не был в class A, потому что теперь reference a указывает на объект class A.

Он полезен во многих сценариях. Например, вы хотите иметь коллекцию объектов, которые указывают на тот же базовый класс. Вместо сохранения отдельных коллекций для каждого подкласса вы поддерживаете единый набор базового класса. И затем, когда вы хотите использовать любой дочерний объект, вы вводите объект базового класса для объекта дочернего класса, чтобы сделать это.

ArrayList<Base> children = new ArrayList<Base>(); 
children.add(new Child1()); 
children.add(new Child2()); 

Console.WriteLine(((Child1)children.get(0)).getChildName()); 
Console.WriteLine(((Child2)children.get(1)).getChildName()); 

Теперь базовый класс не имеет ни одного метода с именем getChild1Name или getChild2Name. И для этого вам нужно создать объект типа базового класса для соответствующего дочернего класса.

+0

Они просят Java. «Список» не может быть создан. Ваши примеры написания имен не только не будут компилироваться, но и противоречат хорошему полиморфному дизайну. – ChiefTwoPencils

+2

Не говоря уже о том, что вы отбрасываете назад. – Linus

+0

@ChiefTwoPencils Спасибо, что указали это. Я просто привел общий пример использования коллекции. Это не язык специфический. Хотя они поставили тег JAVA, но в вопросе они просто задали общий вопрос. –

0

Java неявно взлетает с назначением, поэтому в коде, который вы предоставили, оператор литья избыточен; a уже типа A:

A a = new B(); // without typecast operator (implicit upcast) 
A a = (A)a; // with redundant typecast operator 

Одна из причин, чтобы оператор литья является то, что вы, возможно, пожелает также обратное приведение (не выполняется неявно в Java). Например, когда a тип A ссылка на объект класса B (например, когда B подкласс A) один, возможно, потребуется обратное приведение доступа к определенным методам:

A a = new B(); // implicit upcast 
C c = ((B)a).methodOfBOnly(); // explicit downcast 

Вы также можете проверить this question почему Java не делает скрытого понижения.

Могут быть моменты, когда повышение должно выполняться явно. Например, если класс содержит перегруженные методы

C method(A x){/*does one thing*/} 
C method(B x){/*does another*/} 

и предполагая b имеет тип B, звонки в method((A)b) и method(b) будет вести себя по-разному.

0

Кастинг имеет разные виды использования. К сожалению, ваш пример не использует какой-либо полезный пример кастинга, поскольку вы создаете экземпляр A (a), а затем отбрасываете его на A.

Что вам нужно для понимания, есть вид и актуальные типы. Очевидным типом будет List<T> list;. Здесь мы видим, что это список. Но фактическим типом может быть ArrayList<T> (List<T> list = new ArrayList<>();). В этом сценарии мы с осторожностью можем отобразить видимый тип для фактического типа. Это позволило бы нам использовать функциональные возможности фактического типа. Например, давайте посмотрим на некоторый код; Дано:

List<Integer> list = new ArrayList<>(); 
ArrayList<Integer> aList; 
LinkedList<Integer> lList = new LinkedList<>(); 

Мы можем сделать это без проблем (хотя опасно в целом) ...

// Dangerous but OK with a cast 
// list might not be an ArrayList 
aList = (ArrayList<Integer>) list; 
// Use ArrayList methods 
aList.trimToSize(); 
list = lList; 
LinkedList<Integer> danger = (LinkedList<Integer>) list; 

... но это также можно сделать:

aList = (ArrayList<Integer) list; 
// Use ArrayList methods 
aList.trimToSize(); 
// list = lList; 
LinkedList<Integer> danger = (LinkedList<Integer>) list; 

Последние snippet приводит к ClassCastException, потому что list не является LinkedList.

Кастинг выходит за пределы этого, хотя. Подумайте, когда у вас есть два целых числа, которые вы хотите разделить. Без трансляции вы можете получить целочисленный результат, когда более подходящей является плавающая точка. Рассмотрим:

int i = 2; 
int j = 3; 
System.out.println("No cast: " + i/j + " ;With cast: " + (double)i/j); 

Выход:

Нет ролях: 0; С броском: 0,6666666666666666

Таким образом, это не зависит от случая использования.