Component dependencies - Use this when you want to keep two components independent. 
Subcomponents - Use this when you want to keep two components coupled.
I will use the below example to explain Component dependencies and Subcomponents. Some points worth noticing about the example are:
- SomeClassA1can be created without any dependency.- ModuleAprovides and instance of- SomeClassA1via the- provideSomeClassA1()method.
- SomeClassB1cannot be created without- SomeClassA1.- ModuleBcan provide an instance of- SomeClassB1only if an instance of- SomeClassA1is passed as an argument to- provideSomeClassB1()method.
@Module
public class ModuleA {
    @Provides
    public SomeClassA1 provideSomeClassA1() {
        return new SomeClassA1();
    }
}
@Module
public class ModuleB {
    @Provides
    public SomeClassB1 provideSomeClassB1(SomeClassA1 someClassA1) {
        return new SomeClassB1(someClassA1);
    }
}
public class SomeClassA1 {
    public SomeClassA1() {}
}
public class SomeClassB1 {
    private SomeClassA1 someClassA1;
    public SomeClassB1(SomeClassA1 someClassA1) {
        this.someClassA1 = someClassA1;
    }
}
Dagger will take care of passing the instance of SomeClassA1 as an argument to provideSomeClassB1() method on ModuleB whenever the Component/Subcomponent declaring ModuleB is initialized. We need to instruct Dagger how to fulfill the dependency. This can be done either by using Component dependency or Subcomponent.
Component dependency
Note the following points in the Component dependency example below:
- ComponentBhas to define the dependency via the- dependenciesmethod on- @Componentannotation.
- ComponentAdoesn't need to declare- ModuleB. This keeps the two components independent.
public class ComponentDependency {
    @Component(modules = ModuleA.class)
    public interface ComponentA {
        SomeClassA1 someClassA1();
    }
    @Component(modules = ModuleB.class, dependencies = ComponentA.class)
    public interface ComponentB {
        SomeClassB1 someClassB1();
    }
    public static void main(String[] args) {
        ModuleA moduleA = new ModuleA();
        ComponentA componentA = DaggerComponentDependency_ComponentA.builder()
                .moduleA(moduleA)
                .build();
        ModuleB moduleB = new ModuleB();
        ComponentB componentB = DaggerComponentDependency_ComponentB.builder()
                .moduleB(moduleB)
                .componentA(componentA)
                .build();
    }
}
SubComponent
Note the following points in the SubComponent example:
- As ComponentBhas not defined the dependency onModuleA, it cannot live independently. It becomes dependent on the component that will provide theModuleA. Hence it has a@Subcomponentannotation.
- ComponentAhas declared- ModuleBvia the interface method- componentB(). This makes the two components coupled. In fact,- ComponentBcan only be initialized via- ComponentA.
public class SubComponent {
    @Component(modules = ModuleA.class)
    public interface ComponentA {
        ComponentB componentB(ModuleB moduleB);
    }
    @Subcomponent(modules = ModuleB.class)
    public interface ComponentB {
        SomeClassB1 someClassB1();
    }
    public static void main(String[] args) {
        ModuleA moduleA = new ModuleA();
        ComponentA componentA = DaggerSubComponent_ComponentA.builder()
                .moduleA(moduleA)
                .build();
        ModuleB moduleB = new ModuleB();
        ComponentB componentB = componentA.componentB(moduleB);
    }
}