2

I was going through some design pattern videos on YouTube, however I have a small doubt on some basic Java concept. I tried searching for solution, but was unable to find one. Below is my query.

I have some classes Animal.java, Dog.java, an interface Fly.java which also has a class named CantFly in same file. A main method CheckAnimal.java. Below is the code

Animal.java

package com.classification.pojo;

public class Animal {

    public Fly flyingType;

    public String tryToFly() {
        return flyingType.fly();
    }

    public void setFlyingAbility(Fly newFlyType) {
        flyingType = newFlyType;
    }

}

Dog.java

package com.classification.pojo;

public class Dog extends Animal {
    public Dog() {
        super();
        flyingType = new CantFly();
    }

    public void digHole() {
        System.out.println("I am digging hole!");
    }
}

Fly.java

package com.designpattern.strategy;

public interface Fly {
    String fly();
}

class CantFly implements Fly {

    public String fly() {
        return "Can't fly";
    }
}

class ItFlys implements Fly {
    public String fly() {
        return "I can fly";
    }
}

CheckAnimal.java

package com.designpattern.main;

import com.classification.pojo.Animal;
import com.classification.pojo.Dog;
import com.classification.pojo.Fly;

public class CheckAnimals {

    public static void main(String[] args) {
        Animal doggy = new Dog();
        System.out.println(doggy.tryToFly());
        doggy.setFlyingAbility(new ItFlys());
        System.out.println(doggy.tryToFly());
    }

}

In CheckAnimal.java, for doggy object to invoke setFlyingAbility() method correctly, Animal.java, Dog.java and Fly.java needs to be in same package. If I keep Fly.java in different package, I cannot access CantFly() constructor. I hope I have made my point clear.

- Ishan

4 Answers 4

1

You've declared CantFly without any access modifier:

class CantFly

... which means it's only accessible within the same package. Just make it public, and then you'll be able to use it within other packages. See the Java tutorial on access modifiers for more information. The same is true for the ItFlys class.

Additionally, you haven't imported the right package in your CheckAnimal.java file. You should be importing com.designpattern.strategy.ItFlys. You don't need to import Fly at all in CheckAnimal.java, as you're never referring to that interface directly in that file.

Sign up to request clarification or add additional context in comments.

2 Comments

Apologies for some typo mistakes, I know CantFly is not a method. I have made changes and also updated with necessary comments. Thank You!
@icr: Why have you changed the question so much? You didn't need to introduce ItFlys at all - you've made most of the existing answers into nonsense. Fixing a typo is one thing, but some of the other changes are inconsequential other than to invalidate answers.
1

That's right. You can make the CantFly class public to access it outside of it's package, but note that doing that requires you to put it in its own file.

That is: Create CantFly.java with the following content:

package whatever.package.you.want;
import com.designpattern.strategy.Fly;

class CantFly implements Fly {
    public String fly() {
        return "Can't fly";
    }
}


Also, it shouldn't be new Fly.CantFly() (since you haven't defined CantFly inside the Fly interface). It should be just new CantFly().


If you really want to keep Fly and CantFly in the same file, you can let CantFly be an inner class:

interface Fly {
    ...

    class CantFly {
        ...
    }
}

and then instantiate it with new Fly.CantFly(). If you're fine with this, I'd probably recommend you to consider using an enum instead:

enum FlyCapability {
    CANT_FLY {
        @Override
        public String fly() {
            return "Can't fly";
        }
    },

    CAN_FLY {
        @Override
        public String fly() {
            return "Can fly";
        }
    };

    public abstract String fly();
}

3 Comments

You beat @jonskeet by 14 seconds!
Yes, I know it will work if I put CantFly class in a different file. However I want CantFly class to be in same file as the interface Fly it is implementing. I have changed some stuff for better understanding of Code. If I copy all the code in same package it works as expected. However suppose I move Fly.java in package as I have mentioned above it doesn't...
Updated my answer slightly.
0

First Of all Fly is an interface that cannot be instantiate which you are doing in CheckAnimal class.
Try this:-

package com.designpattern.main;
import com.classification.pojo.Animal;
import com.classification.pojo.Dog;
import com.classification.pojo.Fly;

public class CheckAnimals {
    public static void main(String[] args) {
         Animal doggy = new Dog();
         doggy.setFlyingAbility(new CantFly());

    }
}

and CantFly is no a method it is a class.

Comments

0

This is because the default modifier of a class is package-private, meaning it is visible only by classes in the same package.

You can simply make CantFly a public class defined in its own Java file.

CantFly is not nested inside the Fly interface, so you would need to call its constructor using new CantFly() instead of new Fly.CantFly().

1 Comment

Oops I am sorry, I made a very big typo mistake, it should be doggy.setFlyingAbility(new CantFly());

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.