EIMA
EIMA

Reputation: 11

Interfaces in abstract and inherited classes

For example I have an abstract class which has the IEquatable interface. Based on the properties of this class I want to implement the Equals method in itself (because inherited classes will check equality by these base properties):

abstract class Site : IEquatable<Site>
    {
        public string Name { get; set; }
        public string Adress { get; set; }
        public int Year { get; set; }
        public Site() { }
        public Site(string name, string adress, int year)
        {
            Name = name;
            Adress = adress;
            Year = year;
        }

        public abstract bool CheckIfNew();

        public override bool Equals(object other)
        {
            if(ReferenceEquals(null, other))
            {
                return false;
            }
            if(ReferenceEquals(this, other))
            {
                return true;
            }
            return GetType() == other.GetType() && Equals((Site)other);
        }

        public bool Equals(Site other)
        {
            if (ReferenceEquals(null, other))
            {
                return false;
            }
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            return other.Name == Name && other.Adress == Adress;
        }

        public override int GetHashCode()
        {
            return Name.GetHashCode() ^ Adress.GetHashCode();
        }
    }

Suppose I have two inherited classes. They will both have IComparable interfaces for sorting them in a list. This is one of them:

class Museum : Site, IComparable<Museum>
    {
        public string Type { get; set; }
        private int[] WorkDays { get; set; }
        public bool HasGuide { get; set; }
        public decimal TicketPrice { get; set; }

        public Museum(string name, string adress, int year, string type, int[] workDays, bool hasGuide, decimal ticketPrice)
            : base(name, adress, year)
        {
            Type = type;
            WorkDays = workDays;
            HasGuide = hasGuide;
            TicketPrice = ticketPrice;
        }

        public bool CheckAvailability(int weekDay)
        {
            return WorkDays[weekDay - 1] == 1;
        }
        public override bool CheckIfNew()
        {
            DateTime curent = DateTime.Now;
            int difference = curent.Year * 12 + curent.Month - Year * 12;
            return difference < 24;
        }
        public bool Equals(Museum other)
        {
            return base.Equals(other);
        }

        public override string ToString()
        {
            return base.ToString() + string.Format($" {Type, -20} | {(HasGuide ? "Taip" : "Ne"), -5} | {TicketPrice, 6}");
        }


        public int CompareTo(Museum other)
        {
            return TicketPrice > other.TicketPrice ? 1 : (TicketPrice < other.TicketPrice ? -1 : 0);
        }
    }

Does this inherited class now have both IEquatable and IComparable interfaces? Should I implement Equals method differently in inherited class if I'm checking for equality only by base class properties? Should I add IComparable interface to the base class and make the CompareTo method abstract? If, for example, I would like to store these inherited types in a custom list that only accepts types with these two interfaces, what would be the best way to implement these interfaces? I could go one way or another and it would still, in my opinion, work, but what would be the right and safe way to do this?

Upvotes: 0

Views: 250

Answers (1)

Christopher
Christopher

Reputation: 9814

There is a number of minor differences between Abstract Classes and Interfaces, but one big difference:

Abstract classes are in the inheritance chain. This makes it a primary, exclusive purpose. A Window or Form can not also be a DBConnection

Interfaces are not in the inheritance chain.

The limit about not beign able to declare fields, was invalidated with Properties. If it was no completely removed otherwise.

The limit of not providing Function Implementations, was removed with C# 8.0

A abstract class that "gathers" interfaces is a very common sight.

Should I implement Equals method differently in inherited class if I'm checking for equality only by base class properties?

You should override it anyway. If it adds nothing to change equals, the implemenation is simple:

    public override bool Equals(Museum other)
    {
        return base.Equals(other);
    }

If it does, you you can add that implementaiton.

1:

Upvotes: 1

Related Questions