Используя приведение, вы по существу говорите компилятору: «Поверь мне. Я профессионал, я знаю, что я делаю, и я знаю, что, хотя ты не можешь гарантировать это, я говорю тебе, что это переменная дерева определенно будет красным деревом. "
Поскольку дерево на самом деле не является красным деревом (это дерево, вы можете сделать Tree tree = new Redwood (); и это будет красное дерево), виртуальная машина выдает исключение во время выполнения, потому что вы нарушили это доверие. (вы сказали компилятору, что все будет хорошо, и это не так!)
Компилятор немного умнее, чем просто вслепую принимать все, если вы попытаетесь привести объекты в различные иерархии наследования (например, приведете красное дерево к строке), то компилятор вернет его вам, потому что он знает, что никогда не сможет возможно работа.
Поскольку вы, по сути, просто не позволяете компилятору жаловаться, каждый раз, когда вы приводите, важно убедиться, что вы не вызовете ClassCastException, используя instanceof в операторе if (или что-то в этом роде).
взять ссылку http://www.xyzws.com/Javafaq/why-down-casting-throws-classcastexception/125