-2

there I'm pretty new to Java and have german class and method titles. This Code is meant to give a string output for every class extending "Musiker". I have already looked on SO but my problem is that changing it to static gives an error on the class itself. The main reason why I open a new Question is, that every other class is working as planned. And please don't wonder why the Strings look weird, the Book I copied this from is meant to be humoristic.

public class Proberaum {
public static void main(String[] args) {

    try {

    Musiker saenger = new Saenger();
    Musiker gitarrist = new Gitarrist();
    Musiker bassist = new Bassist();
    Musiker trompeter = new Trompeter();
    Musiker backgroundSaengerin = new BackgroundSaengerin();
    machtMusik(saenger, gitarrist, bassist, trompeter, backgroundSaengerin);

    } catch(Exception e) {
        new Exception().printStackTrace();
    }
}

public static void machtMusik(Musiker... gruppe) {
    for(Musiker musiker : gruppe) {
      musiker.musizieren();
    }
  }


public class Musiker {

    private String name;
    private int alter;
    private Band band;

    public void musizieren() {
        System.out.println("OO Mmmmmmmmh, OO Mmmmmmmmh");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAlter() {
        return alter;
    }

    public void setAlter(int alter) {
        this.alter = alter;
    }

    public Band getBand() {
        return band;
    }

    public void setBand(Band band) {
        this.band = band;
    }
}

public class Band {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class Saenger extends Musiker {

    @Override
    public void musizieren() {
        this.singen();
    }

    public void singen() {
        System.out.println("Oh, bäbi, juuuu a mei sannnnscheiiiiin");
    }
}
public class BackgroundSaengerin extends Saenger {
}

public class Bassist extends Musiker {
}

public class Gitarrist extends Musiker {

    public void musizieren() {
        System.out.println("Tschiiiiiingzäääängggggg");
    }   
}
public class Trompeter extends Musiker {

}

}

N0W0RK
  • 51
  • 1
  • 12
  • The German and the strings aren't a problem, but you really should point out *where* the error message is appearing in the source. Is all of this in one file? – nitind Sep 22 '16 at 05:26
  • Post your stack trace – Sam Orozco Sep 22 '16 at 05:26
  • Yes everything is in one file, the error occours in line three(marked with a comment, Stacktrace will be editet) – N0W0RK Sep 23 '16 at 00:31
  • Related question: http://stackoverflow.com/questions/968347/can-a-java-file-have-more-than-one-class – Jeen Broekstra Sep 23 '16 at 00:57
  • @JeenBroekstra as it concerns me this isn't related at all. When I am wrong, tell me – N0W0RK Sep 23 '16 at 03:10
  • Ok: you're wrong. On a more serious/helpful note: part of your problem looks like it is caused by having several classes defined in a single file. That's bad coding practice in Java, and severely restricts accessibility of your classes. Hence the link to the related question, which provides some background on this. – Jeen Broekstra Sep 23 '16 at 07:22
  • @JeenBroekstra Yes I read the Question, first thank you for that exact answer, but when I delete the Saenger class out of the code, it's working perfectly fine. I get your point and would be annoyed too by duplicate questions but the error is as far as can analyze that not in having multiple classes in one file. What coding practice concerns that program is just to teach java wich is easier when you have everything in one file because stuff can overall often be changed. – N0W0RK Sep 24 '16 at 03:17
  • @JeenBroekstra I rewrote the whole code in different files and actually got this working. but still I think the one above should be working. – N0W0RK Sep 24 '16 at 05:04
  • See my answer for details on why your code doesn't compile. – Jeen Broekstra Sep 24 '16 at 07:02

3 Answers3

1

Your Saenger class is actually a non-static member of the Proberaum class. Because it's non-static, you actually need to create an instance of Proberaum before you can use any of these classes:

Proberaum proberaumObject = new Proberaum();
Musiker saenger = new proberaumObject.Saenger();

In your case, classes inside classes is probably not what you want to do. If you extract each of your classes into its own file, you should find your problem going away. (If that's not possible for whatever reason, declaring your subclasses as static should work too.)

Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
Joe C
  • 15,324
  • 8
  • 38
  • 50
  • I use the code of a book, wich tells me to have public classes. The only thing I could try is extracting the Saenger class etc from the musiker class and have everything in the Proberaum class. – N0W0RK Sep 23 '16 at 00:38
  • I just checked both methods but No. 2 just gives this error:No enclosing instance of type Proberaum is available due to some intermediate constructor invocation. and No. 1 throws this error:Musiker.Saenger cannot be resolved to a type. – N0W0RK Sep 23 '16 at 05:21
  • This answer is not quite correct: `Saenger` is not an inner class of `Musiker`, but of `Proberaum`. So if you wish to follow this approach, instead of creating a `Musiker` you should create a `Proberaum` object. Edited your answer to fix this. – Jeen Broekstra Sep 26 '16 at 22:16
1

Like Joe C also mentioned in his answer: the core of the problem is that your classes Saenger, Musiker, etc etc. are all nested classes (nested inside Proberaum), but they are defined as non-static.

In Java, non-static nested classes are called "inner classes". Inner classes have implicit access to their enclosing class members (even private ones), but of course the flipside of this is that there first needs to be an object of that enclosing class for the inner class to reference. That is why the compiler is complaining in your example: you're trying to create an object of class Saenger, which is an inner class of Proberaum, so to create that object it needs to have a reference to an object of type Proberaum. Since you're doing the object creation in the (static) main method, no such object exists.

So, to fix, you have to change your inner classes. Easiest is to declare them all static. Note that you can do this is in addition to be making them public:

 public static class Seanger extends Musiker { ... 

As also remarked elsewhere however, you really should not put every class in the same file. Learn to work with one class per file, it's the Java Way™.

Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
  • Ok,I get your point but as far I tried, just removing the Saenger class removes the problem, which means t hat all other classes are fine with that. – N0W0RK Sep 24 '16 at 15:47
  • No, the same error will also occur with the other classes. Depending on which compiler you use it's possible you don't immediately see this because of other errors that it detects first. E.g. did you remove the reference to variable saenger in the call to machtMusik? – Jeen Broekstra Sep 24 '16 at 22:01
  • Ok just tested it thank you for being so patient. Can you tell me what exactly about putting the classes in different files fixes the error? – N0W0RK Sep 25 '16 at 01:52
  • If you put them in different files they're no longer nested. So they won't have a dependency on any enclosing class, simply because there _is_ no enclosing class. – Jeen Broekstra Sep 25 '16 at 04:27
0

Instead of declaring the nested classes as static, one can alternatively create objects of nested classes like mentioned below.

Proberaum proberaumObject = new Proberaum();
Musiker saenger = proberaumObject.new Saenger();
  • Please explain why you would want to do this rather than using static classes. As far as I can see it does not provide a good answer to the original question. – tgdavies Aug 19 '20 at 12:54