Implementing IEqualityComparer<T> doesn't override the base implementation of GetHashCode and Equals.
Implementing IEqualityComparer<T> allows you to supply an instance of the implementor as an equality comparer for T. This is a common parameter to several linq extensions and generic collection constructors.
Overriding Equals and GetHashCode effects the way instances of a class are tested for equality. Tapping into other implmentations that call Equals and GetHashCode, like the base = and != operators and linq extensions and generic collection constructors where you don't supply an alternative IEqualityComparer<T>.
These concepts are similar but serve different purposes, they are not partially interchangable.
Let me expand with an example,
public class A
{
    public string Value1 { get; set; }
    public int Value2 { get; set; }
    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;
            hash = (hash * 23) + 
                StringComparer.Ordinal.GetHashCode(this.Value1);
            hash = (hash * 23) + this.Value2;
            return hash;
        }
    }
    public override bool Equals(object obj)
    {
        var a = obj as A;
        if (a == null)
        {
            return false;
        }
        if (a.Value2 != this.Value2)
        {
            return false;
        }
        return StringComparer.Ordinal.Equals(
            a.Value1,
            this.Value1);
    }
}
This implementation of A correctly overrides Equals and GetHashCode, this change is sufficient to ensure that after calling the linq extension
var distinct = aSequneceOfA.Distinct();
distinct will not contain any instances that have both the same Value2 and ordinally comparable Value1. No other interface implementation is necessary to achieve this.
Now, suppose that in some situation I wasn't happy with this ordinal comparison for Value1, perhaps I require some case insensitivity. I might implement an new equality comparer.
public class AComparerInsensitive : IEqualityComparer<A>
{
    public bool Equals(A x, A y)
    {
        if (x == null)
        {
            return y == null;
        }
        if (y == null)
        {
            return false;
        }
        if (x.Value2 != y.Value2)
        {
            return false;
        }
        return StringComparer.CurrentCultureIgnoreCase.Equals(
            x.Value1,
            y.Value1)
    }
    public int GetHashCode(A a)
    {
        if (a == null)
        {
            return 0;
        }
        unchecked
        {
            int hash = 17;
            hash = (hash * 23) + 
                StringComparer.CurrentCultureIgnoreCase.GetHashCode(
                    a.Value1);
            hash = (hash * 23) + a.Value2;
            return hash;
        }
    }
}
This would allow me to call the alternative overload of Distinct,
var insensitivelyDistinct = aSequneceOfA.Distinct(
    new AComparerInsensitive());
This overload of distinct ingnores As overridden Equals and GetHashCode and uses AComparerInsensitive to perform the comparison.