Consider a class with a trivial initialization dependency between slots A and B:

 (defclass super ()
  ((a :initarg :a :reader a)
   (b :initform 0 :initarg :b :reader b)))
 (defmethod initialize-instance :after ((super super) &key &allow-other-keys)
  (setf (slot-value super 'a) (1+ (slot-value super 'b))))
 (a (make-instance 'super)) => 1
 (a (make-instance 'super :b 1)) => 2

You may even subclass it, add an initform and it still works:

 (defclass sub (super)
  ((b :initform 1)))
 (a (make-instance 'sub)) => 2

The complication begins when a subclass adds another slot, C, from which B is to be computed:

 (defclass sub2 (super)
  ((c :initarg :c)))

Say, B is to be initialized to C + 1. That's easy, let's just add a after method, but the after method of the subclass runs after the after method of the superclass, hence the value of A is wrong:

 (defmethod initialize-instance :after ((sub2 sub2) &key c &allow-other-keys)
  (setf (slot-value sub2 'b) (1+ c)))
 (a (make-instance 'sub2 :c 1)) => 1

Sure, it should be a before method. And the previous example is now fixed:

 (defmethod initialize-instance :before ((sub2 sub2) &key c &allow-other-keys)
  (setf (slot-value sub2 'b) (1+ c)))
 (a (make-instance 'sub2 :c 1)) => 3

However, it doesn't work if SUB2 or a subclass of it has an initform on C:

 (defclass sub3 (sub2)
  ((c :initform 2 :initarg :c)))
 (a (make-instance 'sub3)) => error

because C is not passed as an initarg for which the before method is unprepared. At this point one can say screw initforms and use DEFAULT-INITARGS but that's fragile in face of unsuspecting subclasses breaking this convention. Alternatively, one can initialize C early which handles both initforms and initargs fine:

 (defclass sub4 (super)
  ((c :initform 2 :initarg :c)))
 (defmethod initialize-instance :around ((sub4 sub4) &rest initargs
                                        &key &allow-other-keys)
  (apply #'shared-initialize sub4 '(c) initargs)
  (apply #'call-next-method sub4 :b (1+ (slot-value sub4 'c)) initargs))
 (a (make-instance 'sub4)) => 4
 (a (make-instance 'sub4 :c 10)) => 12

That's the best I could come up with, educate me if you have a better idea.

UPDATE: Lazy initialiation has been suggested as an alternative. However, a naive implementation based on SLOT-BOUND-P is bound to run into problems when the lazily computed slot has an initform in a superclass. With SLOT-VALUE-USING-CLASS one can probably mimick most of the semantics here in a very clean manner but to avoid recomputing the value on every access additional bookkeeping is needed, again, due to initforms.