diff --git a/graphene/types/abstracttype.py b/graphene/types/abstracttype.py
index 3948215a..94ed303e 100644
--- a/graphene/types/abstracttype.py
+++ b/graphene/types/abstracttype.py
@@ -2,8 +2,8 @@ import six
 
 from ..utils.is_base_type import is_base_type
 from .options import Options
-from .utils import (get_fields_in_type, merge_fields_in_attrs,
-                    yank_fields_from_attrs)
+from .utils import (get_fields_in_type, get_base_fields,
+                    yank_fields_from_attrs, merge)
 
 
 class AbstractTypeMeta(type):
@@ -19,12 +19,13 @@ class AbstractTypeMeta(type):
                 # raise Exception('You can only extend AbstractTypes after the base definition.')
                 return type.__new__(cls, name, bases, attrs)
 
-        attrs = merge_fields_in_attrs(bases, attrs)
+        base_fields = get_base_fields(AbstractType, bases)
+
         fields = get_fields_in_type(AbstractType, attrs)
         yank_fields_from_attrs(attrs, fields)
 
         options = Options(
-            fields=fields
+            fields=merge(base_fields, fields)
         )
         cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
 
diff --git a/graphene/types/inputobjecttype.py b/graphene/types/inputobjecttype.py
index 4606cf9f..c850fa3f 100644
--- a/graphene/types/inputobjecttype.py
+++ b/graphene/types/inputobjecttype.py
@@ -4,8 +4,8 @@ from ..utils.is_base_type import is_base_type
 from .abstracttype import AbstractTypeMeta
 from .options import Options
 from .unmountedtype import UnmountedType
-from .utils import (get_fields_in_type, merge_fields_in_attrs,
-                    yank_fields_from_attrs)
+from .utils import (get_fields_in_type, yank_fields_from_attrs,
+                    get_base_fields, merge)
 
 
 class InputObjectTypeMeta(AbstractTypeMeta):
@@ -20,14 +20,19 @@ class InputObjectTypeMeta(AbstractTypeMeta):
             attrs.pop('Meta', None),
             name=name,
             description=attrs.get('__doc__'),
-            fields=None,
+            local_fields=None,
         )
 
-        attrs = merge_fields_in_attrs(bases, attrs)
-        if not options.fields:
-            options.fields = get_fields_in_type(InputObjectType, attrs)
-            yank_fields_from_attrs(attrs, options.fields)
+        options.base_fields = get_base_fields(InputObjectType, bases)
 
+        if not options.local_fields:
+            options.local_fields = get_fields_in_type(InputObjectType, attrs)
+            yank_fields_from_attrs(attrs, options.local_fields)
+
+        options.fields = merge(
+            options.base_fields,
+            options.local_fields
+        )
         return type.__new__(cls, name, bases, dict(attrs, _meta=options))
 
     def __str__(cls):  # noqa: N802
diff --git a/graphene/types/interface.py b/graphene/types/interface.py
index 27e2346c..a4cd9703 100644
--- a/graphene/types/interface.py
+++ b/graphene/types/interface.py
@@ -3,8 +3,8 @@ import six
 from ..utils.is_base_type import is_base_type
 from .abstracttype import AbstractTypeMeta
 from .options import Options
-from .utils import (get_fields_in_type, merge_fields_in_attrs,
-                    yank_fields_from_attrs)
+from .utils import (get_fields_in_type, yank_fields_from_attrs,
+                    get_base_fields, merge)
 
 
 class InterfaceMeta(AbstractTypeMeta):
@@ -19,13 +19,19 @@ class InterfaceMeta(AbstractTypeMeta):
             attrs.pop('Meta', None),
             name=name,
             description=attrs.get('__doc__'),
-            fields=None,
+            local_fields=None,
         )
 
-        attrs = merge_fields_in_attrs(bases, attrs)
-        if not options.fields:
-            options.fields = get_fields_in_type(Interface, attrs)
-            yank_fields_from_attrs(attrs, options.fields)
+        options.base_fields = get_base_fields(Interface, bases)
+
+        if not options.local_fields:
+            options.local_fields = get_fields_in_type(Interface, attrs)
+            yank_fields_from_attrs(attrs, options.local_fields)
+
+        options.fields = merge(
+            options.base_fields,
+            options.local_fields
+        )
 
         return type.__new__(cls, name, bases, dict(attrs, _meta=options))
 
diff --git a/graphene/types/objecttype.py b/graphene/types/objecttype.py
index b2cc5960..d9361204 100644
--- a/graphene/types/objecttype.py
+++ b/graphene/types/objecttype.py
@@ -6,8 +6,8 @@ from ..utils.is_base_type import is_base_type
 from .abstracttype import AbstractTypeMeta
 from .interface import Interface
 from .options import Options
-from .utils import (get_fields_in_type, merge_fields_in_attrs,
-                    yank_fields_from_attrs)
+from .utils import (get_fields_in_type, yank_fields_from_attrs,
+                    get_base_fields, merge)
 
 
 class ObjectTypeMeta(AbstractTypeMeta):
@@ -24,23 +24,29 @@ class ObjectTypeMeta(AbstractTypeMeta):
             name=name,
             description=attrs.get('__doc__'),
             interfaces=(),
-            fields=None,
+            local_fields=OrderedDict(),
         )
+        options.base_fields = get_base_fields(ObjectType, bases)
 
-        attrs = merge_fields_in_attrs(bases, attrs)
-        if not options.fields:
+        if not options.local_fields:
             options.local_fields = get_fields_in_type(ObjectType, attrs)
             yank_fields_from_attrs(attrs, options.local_fields)
-            options.interface_fields = OrderedDict()
-            for interface in options.interfaces:
-                assert issubclass(interface, Interface), (
-                    'All interfaces of {} must be a subclass of Interface. Received "{}".'
-                ).format(name, interface)
-                options.interface_fields.update(interface._meta.fields)
-            options.fields = OrderedDict(options.interface_fields)
-            options.fields.update(options.local_fields)
+
+        options.interface_fields = OrderedDict()
+        for interface in options.interfaces:
+            assert issubclass(interface, Interface), (
+                'All interfaces of {} must be a subclass of Interface. Received "{}".'
+            ).format(name, interface)
+            options.interface_fields.update(interface._meta.fields)
+
+        options.fields = merge(
+            options.interface_fields,
+            options.base_fields,
+            options.local_fields
+        )
 
         cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
+
         for interface in options.interfaces:
             interface.implements(cls)
 
diff --git a/graphene/types/utils.py b/graphene/types/utils.py
index 9716a9e4..9f950678 100644
--- a/graphene/types/utils.py
+++ b/graphene/types/utils.py
@@ -19,7 +19,20 @@ def merge_fields_in_attrs(bases, attrs):
     return attrs
 
 
-def unmounted_field_in_type(attname, unmounted_field, type):
+def merge(*dicts):
+    merged = OrderedDict()
+    for _dict in dicts:
+        merged.update(_dict)
+    return merged
+
+
+def get_base_fields(in_type, bases):
+    fields = OrderedDict()
+    fields = merge_fields_in_attrs(bases, fields)
+    return get_fields_in_type(in_type, fields, order=False)
+
+
+def unmounted_field_in_type(unmounted_field, type):
     '''
     Mount the UnmountedType dinamically as Field or InputField
     depending on where mounted in.
@@ -42,27 +55,29 @@ def unmounted_field_in_type(attname, unmounted_field, type):
         return unmounted_field.InputField()
 
     raise Exception(
-        'Unmounted field "{}" cannot be mounted in {}.{}.'.format(
-            unmounted_field, type, attname
+        'Unmounted field "{}" cannot be mounted in {}.'.format(
+            unmounted_field, type
         )
     )
 
 
-def get_fields_in_type(in_type, attrs):
+def get_field(in_type, value):
+    if isinstance(value, (Field, InputField, Dynamic)):
+        return value
+    elif isinstance(value, UnmountedType):
+        return unmounted_field_in_type(value, in_type)
+
+
+def get_fields_in_type(in_type, attrs, order=True):
     fields_with_names = []
     for attname, value in list(attrs.items()):
-        if isinstance(value, (Field, InputField, Dynamic)):
-            fields_with_names.append(
-                (attname, value)
-            )
-        elif isinstance(value, UnmountedType):
-            try:
-                value = unmounted_field_in_type(attname, value, in_type)
-                fields_with_names.append(
-                    (attname, value)
-                )
-            except Exception as e:
-                raise Exception('Exception while mounting the field "{}": {}'.format(attname, str(e)))
+        field = get_field(in_type, value)
+        if not field:
+            continue
+        fields_with_names.append((attname, field))
+
+    if not order:
+        return OrderedDict(fields_with_names)
 
     return OrderedDict(sorted(fields_with_names, key=lambda f: f[1]))