Interfaces, classes and constructors in java

2019-02-28 01:45发布

问题:

Here's something that bothers me regarding Interfaces and classes.

I'm trying to do an implemataion for an interface called IPAddress by a class named IPAddressString. Ipadress contains four parts.

I'm writing a method named mask which mask the current address with the given one. The masking operation is a bitwise 'and' operation on all four parts of the address. You get all the four parts by a method that I wrote named getOctet. (you can see below).

Ok, so I need to mask my this.IpAdress which with it I wrote my class with a new general IPAddress.

While writing the mask I face a problem. I calculated 4 integers that with them I want to return a new IPAddress type. In order to do that I need to use my constructer which returns IPAddressString type, and obivously I cannot convert from IPAddressString to IPAddress.

I'm lost. what should I do? why Isn't my constructure is no good for this? Isn't IPAddressString a sub-type of IPAddress?

Here's the code which will make it simpler:

Here's the Interface:

public interface IPAddress {

    /**
     * Returns a string representation of the IP address, e.g. "192.168.0.1"
     */
    public String toString();

    /**
     * Compares this IPAddress to the specified object
     * 
     * @param other
     *            the IPAddress to compare this string against
     * @return <code>true</code> if both IPAddress objects represent the same IP
     *         address, <code>false</code> otherwise.
     */
    public boolean equals(IPAddress other);

    /**
     * Returns one of the four parts of the IP address. The parts are indexed
     * from left to right. For example, in the IP address 192.168.0.1 part 0 is
     * 192, part 1 is 168, part 2 is 0 and part 3 is 1.
     * 
     * @param index
     *            The index of the IP address part (0, 1, 2 or 3)
     * @return The value of the specified part.
     */
    public int getOctet(int index);

    /**
     * Returns whether this address is a private network address. There are
     * three ranges of addresses reserved for 'private networks' 10.0.0.0 -
     * 10.255.255.255, 172.16.0.0 - 172.31.255.255 and 192.168.0.0 -
     * 192.168.255.255
     * 
     * @return <code>true</code> if this address is in one of the private
     *         network address ranges, <code>false</code> otherwise.
     * @see <a href="http://en.wikipedia.org/wiki/IPv4#Private_networks">Private Networks</a>
     */
    public boolean isPrivateNetwork();

    /**
     * Mask the current address with the given one. The masking operation is a
     * bitwise 'and' operation on all four parts of the address.
     * 
     * @param mask
     *            the IP address with which to mask
     * @return A new IP address representing the result of the mask operation.
     *         The current address is not modified.
     */
    public IPAddress mask(IPAddress mask);
}

Here's my class:

public class IPAddressString {

    private String IpAdress;

    public IPAddressString(int num1, int num2, int num3, int num4) {
        this.IpAdress = num1 + "." + num2 + "." + num3 + "." + num4;

    }


    public String toString() {
        return this.IpAdress;

    }

    public boolean equals(IPAddress other) {
        return ((other.toString()).equals(IpAdress));
    }

    public int getOctet(int index) {

        StringBuffer buf = new StringBuffer();
        int point = index;
        int countPoints = 0;

        for (int i = 0; i <= IpAdress.length() - 1; i++) {
            if ((IpAdress.charAt(i)) == '.') {
                countPoints++;

            }
            if ((countPoints == point) && IpAdress.charAt(i) != '.') {
                buf.append(IpAdress.charAt(i));
            }

        }
        String result = buf.toString();
        return Integer.parseInt(result);
    }

    public boolean isPrivateNetwork() {

        if (getOctet(0) == 10) {
            return true;
        }

        if (getOctet(0) == 172) {
            if (getOctet(1) >= 16 && getOctet(1) <= 31) {
                return true;
            }
        }

        if (getOctet(0) == 192) {
            if (getOctet(1) == 168) {
                return true;
            }
        }

        return false;

    }


    public IPAddress mask(IPAddress mask){
        int n0= mask.getOctet(0) & getOctet(0);
        int n1= mask.getOctet(1) & getOctet(1);
        int n2=mask.getOctet(2) & getOctet(2);
        int n3=mask.getOctet(3) & getOctet(3);



         IPAddress n1= new IPAddressString (n0,n1,n2,n3);
    }

}

The problem again is with the method mask. I need to return a new IPAddress, but I should use my constructure. what am I missing?

Thank you.

回答1:

You can implement IPAddress in IPAddressString. Although you are implementing all the methods of IPAddress interface in your IPAddressString class, you are not telling this to the compiler [which clearly cannot guess your intentions].

change the definition of your class to :

class IPAddressString implements IPAddress

This should solve the problem in conversion.

Now this line:

IPAddress n1= new IPAddressString (n0,n1,n2,n3);

will not give you problems since the hierarchy is established. And you can peacefully return n1.



回答2:

A simple public class IPAddressString implements IPAddress will solve the problem.

Another suggestion that jumped to my eye:

It doesn't make any sense to declare the equals and toString() method in the interface because every object already has them. You wouldn't get a compile error if you didn't implement it.

Furthermore, the equals method must always have the signature boolean equals(Object other), because only then it overrides the method of Object and will be called correctly at all time.