I think you're definition of a class, is probably more what in Java/C#/... is a class.
If you write:
class Eq a => EQ a where
eq :: a -> a -> Bool
eq = (==)
You only define a typeclass: a way to add functions to a type class and write restrictions. You have not written that every Eq a is an EQ a... You have written that in order to implement EQ a, you have to implement Eq a as well (which is a bit weird here).
Furthermore you have provided a default implementation: eq = (==), but that is only a default implementation for an instance where you do not specify the implementation.
By writing:
instance EQ Int where
eq = (==)
you have now defined that Int is an EQ. You can make the instance more useful by writing for instance:
instance Eq a => EQ a
Now you have written than all types a for which Eq a holds, also are a type instance of EQ. If you write that however, you have immediately defined the entire universum of EQ since in your class definition, you restricted a to be an instance of EQ, so that means that now, in the entire Haskell universe, eq is equal to (==).
You probably want to say:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
class EQ a where
eq :: a -> a -> Bool
instance Eq a => EQ a where
eq = (==)
Now you defined a typeclass EQ and for every type a that is Eq a, we set eq to (==), but it allows you to define an EQ over other types as well, like data Foo that is not an instance of Eq. Mind that we have to turn on two extensions here. These are compiler specific, and thus are not part of standard Haskell.