Java有关内部类实现接口及抽象类问题


//Ex6_7.java
abstract class Pencil{
    abstract public int value();
}
interface Paper {
    String mark();
}
class WriteStory() {
    private class MyPencil extends Pencil {
        private int i=5;
        public int value() {
            return i;
        }
    }
    protected class MyPaper implements Paper {
        private String line;
        private MyPaper(String str) {
            line=str;
        }
        public String mark() {
            return line;
        }
    }
    public Paper writeDown(String s) {
        return new MyPaper(s);
    }
    public Pencil pen() {
        return new MyPencil();
    }
}
public class Ex6_7 {
    public static void main(String[] args) {
        WriteStory w= new WriteStory();
        Paper c=w.writeDown("Hello");//*
        System.out.println(c.mark());
        Pencil d=w.pen();//*
        System.out.println(d.value());
    }
}

这是我从教材抄的关于内部类、接口、抽象类的Java程序例子,我对用“//*”标注的两行代码有疑惑。其中Pencil d=w.pen();可以理解为由pen()方法获取抽象类子类的MyPencil的对象,其又通过向上转型赋值到抽象类Pencil的对象吗?那么Paper c=w.writeDown("Hello");怎么理解?

是的,Pencil d=w.pen() 可以理解为通过 pen() 方法获取 MyPencil 的实例,并将其向上转型为 Pencil 类型。

对于 Paper c=w.writeDown("Hello"),writeDown() 方法返回的是 MyPaper 的实例,而 MyPaper 实现了 Paper 接口,因此可以将其向上转型为 Paper 类型,并将其赋值给 c 变量。这个方法可以用来写下一些文本,并生成一张纸张的实例。在本例中,writeDown("Hello") 实际上生成了一张包含 "Hello" 字符串的paper。

抽像类的子类对象是可以赋给抽像类的(接口同理),这样就可以设计一些通用方法来调用不用实现的相同方法

首先你的理解是正确的。在Pencil d=w.pen();这行代码中,pen()方法返回一个MyPencil对象,并将其向上转型为抽象类Pencil。因为子类MyPencil是从抽象类Pencil派生出来的,所以它可以赋值给Pencil类型的变量。
而对于Paper c=w.writeDown("Hello");这行代码,writeDown(String s)方法返回一个实现了Paper接口的MyPaper对象。在这个方法内部,创建了一个MyPaper对象并将字符串s传递给构造函数。然后,该对象被返回并赋值给类型为Paper的变量c。因为MyPaper实现了Paper接口,所以它可以赋值给Paper类型的变量。在这个例子中,返回的MyPaper对象将其mark()方法的返回值设置为“Hello”。在主程序中,调用了c.mark()方法并将其结果打印到控制台上。因此,这个程序将会输出“Hello 5”。