我有一个名为Tree的超类和一个名为AVLTree的子类,它扩展了类Tree。
树的子项也是Tree类型。 AVLTree有AVLTree的孩子。我想使用我在Tree类上编写的方法,在这种情况下getLeft(返回左子)和setLeft(设置左子)。
问题是编译器无法将树转换为AVLTree,即使它们具有相同的变量,结构和构造函数。
关于如何解决这个问题的任何想法?或者我应该只写一个AVLTree在Tree类上的所有方法吗?
代码:
Tree.java:
public class Tree<T extends Tree<T>> {
private T left = null;
private T right = null;
private Object data = null;
public Tree () {
//nothing
}
public Tree (Object data, T left, T right) {
this.data = data;
this.left = left;
this.right = right;
}
public Tree (Object data) {
this.data = data;
}
//Get Values
public T getLeft() {
return this.left;
}
public T getRight() {
return this.right;
}
public Object getData() {
return this.data;
}
//Set Values
public void setLeft(T left) {
this.left = left;
}
public void setRight(T right) {
this.right = right;
}
public void setData(Object data) {
this.data = data;
}
public T treeFromText(String in) {
if (in=="()") return null;
int i=0;
T result = null;
//Find expression
int d = in.indexOf('c')+1;
if (d==0) return null;
int begl, endl, begr, endr;
begl = d+1;
endl = ClosingParentesis(in,begl);
endr = in.length()-2;
begr = OpeningParentesis(in,endr);
T left = null, right = null;
if (begl-endl==0) {
left = null;
} else left = treeFromText(in.substring(begl,endl+1));
if (begr-endr==0) {
right = null;
} else right = treeFromText(in.substring(begr,endr+1));
result.setData(in.charAt(d));
result.setLeft(left);
result.setRight(right);
return result;
}
public static int ClosingParentesis(String in, int openPos) {
int closePos = openPos;
int counter = 1;
while (counter > 0 && closePos < in.length()-1) {
closePos++;
if (in.charAt(closePos)=='(') counter++;
if (in.charAt(closePos)==')') counter--;
}
return closePos;
}
public static int OpeningParentesis(String in, int closePos) {
int openPos = closePos;
int counter = 1;
while (counter > 0 && openPos > 0) {
openPos--;
if (in.charAt(openPos)=='(') counter--;
if (in.charAt(openPos)==')') counter++;
}
return openPos;
}
AVLTree.java:
public class AVLTree extends Tree<AVLTree> {
/*
//Values and Variables
private AVLTree left = null;
private AVLTree right = null;
private Object data;
//Inicialization
public AVLTree (Object data, AVLTree left, AVLTree right) {
super(data,left,right);
}
public AVLTree (Object data) {
super(data);
}
*/
public int getfactor() {
return getHeight(this.getLeft())-getHeight(this.getRight());
}
}
Test.java:
public static void main(String[] args) {
AVLTree tree = new AVLTree();
Scanner console = new Scanner(System.in);
String in = console.nextLine().toLowerCase();
tree = (AVLTree) tree.treeFromText(in); //The error is here.
System.out.println(tree.getHeight());
System.out.println(tree.TreePreOrder());
}
我期望它的工作方式是,如果字符串&#39;在&#39;在Test.java中是&#34;(c3()(c2()()))&#34;返回值必须是值为3的Tree和值为2的右子。此返回值必须是Tree类型或任何扩展Tree的值。
答案 0 :(得分:0)
你可以通过泛型的力量来实现这一点:定义一个新的循环泛型T:
public class Tree<T extends Tree<T>>
{
T left;
T right;
public T doSomething()
{
return left;
}
public static class AVLTree extends Tree<AVLTree>
{
public AVLTree foo()
{
return doSomething();
}
}
}
更新:以下是创建不同树实例的方法:
import java.util.Objects;
public class TreesFactory
{
public static AVLTree createAVLTreeFrom(String in)
{
return treeFromText(in, AVLTree::new);
}
@FunctionalInterface
interface SimpleFactory<T extends Tree<T>>
{
T createNew();
}
public static <T extends Tree<T>> T treeFromText(String in, SimpleFactory<T> treeFactory)
{
if (Objects.equals(in, "()"))
return null;
T result = treeFactory.createNew();
//Find expression
int d = in.indexOf('c') + 1;
if (d == 0)
return null;
int begl, endl, begr, endr;
begl = d + 1;
endl = ClosingParentesis(in, begl);
endr = in.length() - 2;
begr = OpeningParentesis(in, endr);
T left, right;
if (begl - endl == 0)
{
left = null;
}
else
left = treeFromText(in.substring(begl, endl + 1), treeFactory);
if (begr - endr == 0)
{
right = null;
}
else
right = treeFromText(in.substring(begr, endr + 1), treeFactory);
result.setData(in.charAt(d));
result.setLeft(left);
result.setRight(right);
return result;
}
public static int ClosingParentesis(String in, int openPos)
{
int closePos = openPos;
int counter = 1;
while (counter > 0 && closePos < in.length() - 1)
{
closePos++;
if (in.charAt(closePos) == '(')
counter++;
if (in.charAt(closePos) == ')')
counter--;
}
return closePos;
}
public static int OpeningParentesis(String in, int closePos)
{
int openPos = closePos;
int counter = 1;
while (counter > 0 && openPos > 0)
{
openPos--;
if (in.charAt(openPos) == '(')
counter--;
if (in.charAt(openPos) == ')')
counter++;
}
return openPos;
}
}
主要:
public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
String in = console.nextLine().toLowerCase();
AVLTree tree = TreesFactory.createAVLTreeFrom(in);
//...
}
答案 1 :(得分:0)
您需要一种方法,使用AVLTree
中的逻辑从String
实例化Tree.treeFromText
。
将Tree
声明为abstract
。
在Tree
中创建一个新方法:
abstract protected T createEmptyTree();
在AVLTree
中覆盖该方法,以返回AVLTree
的空实例。
@Override
protected AVLTree createEmptyTree() {
return new AVLTree();
}
在treeFromText()
中,只要您需要创建T
的空实例,请调用createEmptyTree()
。
你已经拥有了其余的逻辑。
尽量避免在任何地方返回null
。最好返回空AVLTree
而不是null
。