Let me dwell on the comments of Antonov. The question is when can you use B for A. Usually you can do this when B is a subtype of A. For example, you can assign a UITableView variable of type UIView .
So, when is something a subtype of something else?
For classes, it's simple: if you are a subclass of B from A , B is a subtype of A
For function types, you need to consider argument types and return type. The type of the function F2 is a subtype of the type of the function F1 , if the parameter types F2 s are supertypes of the parameter F1 s, and the type of the return type F2 is a subtype of the return type F1 s. You could say that a function should not require more (i.e., it does not require subtypes as parameters, but may require supertypes) and should not provide less (i.e., it should not return a supertype, but may return a subtype) , since its type is a subtype, the terminology is that the parameter types must be contravariant, and the return type must be covariant.
Example:
var f1: UIControl -> UIControl = ... let f2: UIView -> UIControl = ... let f3: UIControl -> UIButton = ... let f4: UIView -> UIButton = ... f1 = f2
Thus, types F2 , f3 and f4 are subtypes of type F1 s, while types f5 , f6 and f7 are not.
What about generic types? In Swift, custom types with type parameters are all invariant. That is, in your example, the Class1<T2> object cannot be used as the Class1<T1> object, regardless of the relationship between T1 and T2 (unless T1 and T2 are the same type).
However, Swift has some built-in dispersion rules that make your example work with arrays: [UITableView] ( Array<UITableView> ) is a subtype of [UIView] ( Array<UIView> ). Please note that the same is true for options, i.e. UITableView? ( Optional<UITableView> ) is a subtype of UIView? ( Optional<UIView> ). Thus, both arrays and additional modules are covariant with their type parameter.
Further reading: