Java OO概念

时间:2011-04-07 05:05:54

标签: java oop

美好的一天!

我正在审查Java OO概念。 并编写了以下代码:

  public class Main {  
        public static void main(String[] args) {
            Animal dog = new Dog();
            dog.eat();
            dog.sleep();
        }

    }

abstract public class Animal {

    private int age;
    public Animal (){
        age = 1;
    } 
    public Animal (int age){   //How can I call this constructor?
        this.age = age;
    }
    public void eat(){
        System.out.println("Eat");
    }
    abstract public void sleep();
}

abstract public class Canine extends Animal{

    abstract public void roam();

}

public interface Pet {

    public String petName = null;  //i want the pets to have a variable petName.
    public void trick();
    }


public class Dog extends Canine implements Pet{

    public void roam(){
        System.out.println("roam");
    };

    public void sleep(){
        System.out.println("sleep");
    };

    public void eat(){
        System.out.println("Eat Dog");
    };

    public void trick(){
        System.out.println("trick");
    }

}

我有几个问题如下:

  1. 如何调用Animal Overloaded构造函数?

  2. 如何在PET界面中使用变量petName?

  3. 我是否正确地做了OO的概念?我违反了什么规则?

  4. 提前谢谢。

6 个答案:

答案 0 :(得分:3)

  1. 子类将使用super(...)作为第一行从他们自己的构造函数中调用超级构造函数!
  2. 接口不能有变量或只有状态的方法!
  3. 您有一个合理的概念,但您的代码无法编译(因为上面的第2项)。
  4. 一些解决方案:

    public interface Pet {
        String getName();
        void trick();
    }
    

    现在Dog类(或任何实现Pet的类)必须实现Pet.getName()。为Dog类提供一个名为'name'的String类型的字段,并从Dog.getName()返回它。

    public abstract class Canine extends Animal {
        public Canine(int age) {
            super(age); // pass the age parameter up to Animal
        }
        ...
    }
    
    public class Dog extends Canine implements Pet {
        private final String name;
        public Dog(String name,int age) {
           super(age); // call the age constructor
           this.name=name;
        }
        public String getName() { return name; }
        ... rest of class ...
    }
    

    每个子类(尤其是抽象的子类)都需要为要调用的所有父类构造函数提供匹配的构造函数! (所以我将年龄参数添加到Canine构造函数中,以便Dog可以将年龄参数传递给它。

答案 1 :(得分:2)

答案 2 :(得分:1)

1)你可以将争论的构造函数称为“this(20);”

显式构造函数调用的示例

  

公共课点{

     

int mx;

     

int my;

//============ Constructor
public Point(int x, int y) {
    mx = x;
    my = y;
}

//============ Parameterless default constructor
public Point() {
    this(0, 0);  // Calls other constructor.
}
. . .

} super(...) - 超类(父)构造函数 对象具有自己的类的字段以及其父类的所有字段,祖父类,一直到根类Object。有必要初始化所有字段,因此必须调用所有构造函数! Java编译器会在构造函数链接过程中自动插入必要的构造函数调用,或者您可以显式地执行此操作。

如果没有构造函数调用作为构造函数的第一个语句,Java编译器会插入对父构造函数(super)的调用。以下是上面的构造函数的等价物。

//============ Constructor (same as in above example)
public Point(int x, int y) {
    super();  // Automatically done if you don't call constructor here.
    m_x = x;
    m_y = y;
}Why you might want to call super explicitly

通常,您不需要为父类调用构造函数,因为它是自动生成的,但有两种情况需要这样做。

您想调用具有参数的父构造函数(自动生成的超级构造函数调用没有参数)。 没有无参数的父构造函数,因为只有父类中定义了带参数的构造函数。

答案 3 :(得分:1)

  1. 调用任一构造函数都会调用重载的构造函数:两个构造函数都使用相同的名称。要调用带有int的构造函数,请调用dog = new Dog(1);

  2. 课程Dog实施Pet,因此它会有一个公开字段petName(是super.petName吗?)。

  3. 我没有看到任何根本性的错误。

答案 4 :(得分:1)

  1. 对父构造函数的调用是super();在你的情况下,例如super(12);。请注意,对构造函数(this()super())的调用必须是第一个语句。请注意,您只能上升一个级别,因此要调用Animal中的构造函数,“ d必须将其编码为Canine而不是Dog

    public Dog(int age)
    {
         super(age); //this will invoke Canine's overloaded constructor
    }
    
    
    //You must now provide the overloaded constructor in Canine which invokes
    //the overloaded constructor in Animal
    public Canine(int age)
    {
         super(age); //this will invoke Animal's overloaded constructor
    }
    
  2. 您可以访问Pet.petName的值,以及Pet.petName。这是因为Interface只能有方法(隐式public)和常量(隐式public static final)。你可以使用this.petName,但这是毫无意义的(并且可能令人困惑)。您无法在其他地方设置petName的值,因为它是final,即使您没有声明它也是如此。

    但是在这种情况下,将名称声明为接口的一部分没有意义,因为它不是常量。它应该是一些抽象或具体类的一部分,以便可以按Pet的每个实例设置它。你应该为Pet -

    定义一个getter(也许是一个setter)
    public String getName();
    public String setName(String name);
    

    这些将强制实现类提供某种实现来获取和设置Pet的名称,而不强制该名称存储在该类的内部。

答案 5 :(得分:1)

How can I call the Animal Overloaded constructor?

你需要链接它。

abstract public class Canine extends Animal{
    public Canine(int age) {
            super(age);
    }
    // ...
}

public class Dog extends Canine implements Pet{

public Dog(int age) {
            super(age);
    }
   //...
}


How can I use the variable petName in the PET Interface?


Pet.petName。如果一个类实现了这样的接口,那么该类可以引用那些没有合格类名的常量,如下所示:petName

Am I doing the concept of OO correctly? What rules am I violating?

Interface constants