我如何在java中操作类

时间:2013-01-06 23:27:07

标签: java javascript class dynamic

我知道sereval编程语言。其中大多数是脚本语言,如lua,perl,JS,ruby等。

但是最近,我开始使用Java进行编程,这是非常有效的。所以我一直在思考JS中存在的某个函数。构造函数的原型,即。为了进一步理解我的问题,我将在JS中做一个例子。假设你想创建一个狗的应用程序。

function dog (){
this.property1 = value;
this.propertr2 = value2;
this.propertyN = valueN;
//et.c.
}

//now, I will create sereval instances of the constructor in JS

var snoopy = new dog();
var buddy = new dog();

和我所知道的关于JS的很棒的部分是你可以动态改变 构造函数的信息以及构造函数的所有实例 (在JS中调用)使用这样的prototype关键字:

dog.prototype.bark = function () {
console.log("Woof!");
};

和THIS,不仅会更改有关构造函数的信息,因此每个将使用构造函数创建的狗都知道如何发布,它也会发生变化,以便构造函数的所有实例都获取原型插入在这种情况下教狗狗如何吠叫。我们可以在下一个例子中看到:

var someOtherDog = new dog ();
someOtherDog.bark(); //output will be: Woof!
snoopy.bark();       //output will also be: Woof!
buddy.bark();        //you guest it! it will also be: Woof!
     

因此,使用JS中的这个prototype关键字,我可以操作构造函数及其实例。现在,我的问题是:

我如何操纵java中的类及其实例?甚至可能吗? 如果是这样;我应该怎么做才能在java中做这样的事情?

class dog
{
    private String hairColor;
    public dog ()
    {
        hairColor = "Brown";
    }
    public static void main (String args[])
    {
        dog snoopy = new dog ();
        dog buddy = new dog ();
        //now, how do I manipulate the class like I did in JS?
    }
}

3 个答案:

答案 0 :(得分:1)

问题是lua和JavaScript都是基于原型的,而Java则不是。您可以使用反射来完成类似的操作,但不能使用JavaScript级别。 Reflection

答案 1 :(得分:1)

如果需要,您可以动态创建匿名类。

假设你有一个班级:

class Dog {
    String name;
    Dog(String name) { this.name = name; }
    void bark() { System.out.println(name + " says 'woof!'"); }

    public static void main(String...args) { 
        Dog snoopy = new Dog("snoopy");
        snoopy.bark();
    }

}

这是结果

c:\files\j>javac Dog.java

c:\files\j>java Dog
snoopy says 'woof!'

现在伙计他不说低声 - 他说皱纹!所以我们就像这样创建一个

class Dog {
    String name;
    Dog(String name) { this.name = name; }
    void bark() { System.out.println(name + " says 'woof!'"); }

    public static void main(String...args) { 
        Dog snoopy = new Dog("snoopy");
        snoopy.bark();
        Dog buddy = new Dog("buddy") {
            @Override void bark() { System.out.println(name + " says 'ruff!'"); }
        };
        buddy.bark();
    }

}

结果是

c:\files\j>javac Dog.java

c:\files\j>java Dog
snoopy says 'woof!'
buddy says 'ruff!'

如果你想永久改变每条狗,那就更难了,但可以通过策略模式来完成。

假设我们有以下

abstract class BarkingStrategy {
    public abstract void doBark(Dog dog);
}

class TypicalBarkingStrategy extends BarkingStrategy {
    public void doBark(Dog dog) { System.out.println(dog.getName() + " says 'woof!'"); }
}

class AggressiveBarkingStrategy extends BarkingStrategy {
    public void doBark(Dog dog) { System.out.println(dog.getName() + " says 'Rrrruff!'"); }
}

class Dog {
    // notice this is static - that means it belongs to the class itself, not 
    // any particular instance of it - similar to prototype
    static BarkingStrategy bark = new TypicalBarkingStrategy();
    String name;
    Dog(String name) { this.name = name; }
    String getName() { return name; }
    void bark() { bark.doBark(this); }
}

然后你可以做以下

public static void main(String...args) {
    Dog snoopy = new Dog("snoopy");
    snoopy.bark();
    Dog.bark = new AggressiveBarkingStrategy();
    snoopy.bark();
}

这导致

c:\files\j>javac Dog.java

c:\files\j>java Dog
snoopy says 'woof!'
snoopy says 'Rrrruff!'

答案 2 :(得分:1)

JavaScript中的继承由原型链完成。基本上,如果在bark对象中找不到snoopy,则会在原型snoopy.prototype中查找它。如果在那里找到,则使用该版本。如果不是(例如在调用bark.toString()时),则遍历原型链,直到找到具有该成员的原型。原型本身在所有“实例”之间共享,因为它只是一个普通对象,您可以在以后添加或删除成员。

Java中的继承是基于类的。除非重新编译并重新加载整个类,否则无法在运行时从类定义中添加或删除成员。这是一种不同的编程范式,这意味着你必须使用其他技术和模式(稍微)对它进行编程。