Defining Gap Problems
Gap problems are examples of promise problems, which are really the three-valued logic analogs of languages: some elements are in the language, some elements are not, and for the rest, we don't care.

A promise problem is in P if there is a polynomial time algorithm that answers Yes on all Yes instances and No on all No instances; we don't care what it answers on the don't care instances.

A promise problem $L$ is NP-hard if for every NP problem $L'$ there is a polytime reduction $f$ such that if $x \in L'$ then $f(x)$ is a Yes instance of $L$, and if $x \notin L'$ then $f(x)$ is a No instance of $L$.

We can similarly define the analogs of many other properties of languages. Usually this is done in an ad-hoc basis. We definitely think of promise problems as single languages rather than as a class of languages.