-6

I'm trying to learn Java using DrJava.

When I try to run this bit of code DrJava tells me:

Static Error: This class does not have a static void main method accepting String[].

What I don't get is why DrJava tells me there's no main. It's the first line after the class canine declaration; and I don't see any typos or missing punctuation.

I tried Googling this, but I didn't understand what they were talking about.

Would be nice if someone can clue me in, in a way that doesn't actually give me the answer, but leads me figure it out on my own why this is happening to me -but if the problem is too basic to create a learning opportunity, then I'll take a solution; I guess.

/*
 * This is an exercise designed to practice creating a class Animal
 * And then creating another class canine in which to create an object dog.
 * The reason I want to call from one class to another is because I want 
 * to understand how classes, objects, inheritance, etc. works. 
 * Clearly, class canine is -in my mind at least, a child of class Animal.
 * The main method of canine then calls method attributes I think are being
 * inherited by dog and wolf,from the class Animal.    
 */

public class Animal {
  void growl() {
    System.out.println("Grrr");
  }
  void bark() {
    System.out.println("Arf! Arf!");
  }
}

class canine {
  public static void main(String[]args) {
    Animal dog = new Animal();
    dog.bark();

    Animal wolf = new Animal();
    wolf.growl();

  }
}
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Gavinaldi
  • 1
  • 2
  • How is canine a child class from Animal? And why do you need it to be a child class? – isaace Sep 04 '17 at 15:32
  • 1
    Put each class in its own file, files with the same name as the class. The class should be public, and the main method should be in one of those public classes. – Hovercraft Full Of Eels Sep 04 '17 at 15:33
  • That code runs just fine with the `java` command-line tool: `java canine` – T.J. Crowder Sep 04 '17 at 15:33
  • @HovercraftFullOfEels: While it's good practice, since only one of those classes is public, the above works as-is. – T.J. Crowder Sep 04 '17 at 15:33
  • @T.J.Crowder: it would simplify things immensely, and make him less likely to make basic errors. – Hovercraft Full Of Eels Sep 04 '17 at 15:35
  • @isaace Need is a strong word. It's not a need. It is a search for understanding how inheritance, objects, etc. relate and work. – Gavinaldi Sep 04 '17 at 15:35
  • 3
    Well, at the moment you don't have any inheritance relationship. If you wanted `canine` to be a child class, it would be something like `class Canine extends Animal` – Jon Skeet Sep 04 '17 at 15:37
  • @T.J.Crowder I get what command line tool is. I get that by using java canine in cmd it is running the file. But I still don't understand why DrJava is telling me that it doesn't have a static void main method accepting String[]. Also, It's not printing anything, when I run on DrJava. – Gavinaldi Sep 04 '17 at 15:39
  • 1
    @Gavinaldi: Well, there was no indication in the question you knew that. In any case, I've added a note to the answer below. I expect you're just confusing DrJava with the non-best-practices approach. – T.J. Crowder Sep 04 '17 at 15:41
  • @JonSkeet but doesn't dog.bark() directly call the function in Animal? Why do I need to "extend" in this scenario? I thought extending was for classes in separate files (kind of like import) – Gavinaldi Sep 04 '17 at 15:42
  • 3
    Read [*What is Inheritance?*](http://docs.oracle.com/javase/tutorial/java/concepts/inheritance.html) – Basil Bourque Sep 04 '17 at 15:43
  • @Gavinaldi Not every kind of animal barks: fish, birds, gerbils. So `bark` belongs in a subclass of `Animal` such as `Canine extends Animal` as only canines bark. – Basil Bourque Sep 04 '17 at 15:46
  • 4
    In the future, please take a bit more care in how your question is presented. Rants and other types of abusive language are not allowed on Stack Overflow. Another user and myself have edited your question to remove this language. Since this is your first offense and you are new here, I'm letting you off with a warning. Repeated offenses will, however, result in penalties, if users flag your posts as "rude/abusive" like they did the initial draft of this one. – Cody Gray - on strike Sep 04 '17 at 15:49
  • @CodyGray You're right. I let my frustration get the best out of me, and I kind of let that seep into my OP. I'll try to keep the head-smashing into keyboard private, in the future. – Gavinaldi Sep 04 '17 at 15:52
  • 1
    Yes, dog.bark() calls the method in Animal, but you said you wanted to investigate inheritance - you're not using inheritance at all in the code you posted. – Jon Skeet Sep 04 '17 at 16:02
  • And in particular: "Clearly, class canine is -in my mind at least, a child of class Animal." No, it's not. – Jon Skeet Sep 04 '17 at 19:36
  • @JonSkeet Yes, I see now that I was under the mistaken impression that simply using another classes' method the object making the call somehow became child to the class/object hosting the method. – Gavinaldi Sep 05 '17 at 01:09

1 Answers1

3

That code runs just fine with the java command-line tool: java canine

When you do java canine, you'll telling the java tool to find and load the canine class and run its main method.

If you were using java Animal, the issue is that Animal has no main. canine does.

Clearly, class canine is -in my mind at least, a child of class Animal

No, there is no relationship between canine and Animal other than that canine uses Animal in its main. E.g., canine depends on Animal but isn't otherwise related to it. If you wanted it to be a subclass (one fairly reasonable interpretation of "child class"), you'd add extends Animal to its declaration. If you wanted it to be a nested class (another fairly reasonable interpretation of "child class"), you'd put it inside Animal.

From your comment:

But I still don't understand why DrJava is telling me that it doesn't have a static void main method accepting String[]. Also, It's not printing anything, when I run on DrJava.

I expect you're confusing DrJava by putting canine in the same file as Animal, making Animal public, and then expecting DrJava to figure out that it should run canine.main rather than Animal.main. See the notes below about best practices.

From another comment:

but doesn't dog.bark() directly call the function in Animal? Why do I need to "extend" in this scenario?

You don't. A class can use another class without there being any inheritance relationship between them, as your code does. It was your use of the term "child class" in the comments that suggested you'd intended inheritance or similar.


Side note: While you don't have to follow them, following standard Java naming conventions is good practice. Class names should be initially-capped and CamelCase. So Canine rather than canine.

Side note 2: As Hovercraft Full Of Eels says, it's best to put each class in its own .java file, named by the name of the class. Technically, you can put non-public classes in any .java file (which is why that code works with canine in Animal.java), but in general, again, best practice is to separate them. So you'd have Animal.java containing the Animal class, and canine.java containing the canine class (or better, Canine.java containing the Canine class).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks for the feedback... Based on what I could understand from your reply, I decided to remove public from Animal; that didn't fix the problem. But then I also switched the order. I put the class canine on top, and moved Animal to the bottom, and that worked. But I think I now have more questions than before. – Gavinaldi Sep 04 '17 at 16:08
  • after you brought my attention that cmd can execute java Canine, I decided to try eclipse. The snippet of code worked and ran as expected. Removing 'public' was not necessary, but DrJava seems to mind that the first class listed doesn't contain the main function. Am I wrong in thinking that traditionally, if a chunk of code living within the same file is to be executed, the function containing the main method should be listed first? Or, simply, as you reiterate in note 2: I should [always?] put Animal in a separate file; even for so short a snippet of code? – Gavinaldi Sep 05 '17 at 01:25
  • @Gavinaldi: I'm not aware of a tradition in this regard (other than the best practice). I think it's nothing more significant than a minor bug in DrJava. – T.J. Crowder Sep 05 '17 at 06:26