defineAttributes and rules
You need both because there is no way to define custom validation rules from defineAttributes().

Ultimately things like 'maxLength' =&gt; 14 in defineAttributes() automagically get normalized down to the $rules array that gets returned from the rules method, so you're just appending your custom rule onto that when you call:

$rules = parent::rules();
$rules[] = ['email', 'Craft\MyPlugin_EmailValidator'];