The framework uses event-driven programming. You write handlers that respond to interface events as they occur. The events may or may not have been triggered by user interaction.
In the Lightning Component framework, events are fired from JavaScript controller actions. Events can contain attributes that can be set before the event is fired and read when the event is handled.

Aura framework recommend to use component event type while communicating between child to Parent but in this tutorial we will learn how to Lightning Component Child-Parent Communication happen without Event:

Demp.app

<aura:application extends="force:slds" >
	<c:ComponentA/>
</aura:application>

ComponentA.cmp (Parent Component)

<aura:component>
	<c:ComponentB aura:id="compB" method="{!c.parentPress}"/>
</aura:component>

ComponentA.js (Parent Component)

({
    parentPress : function(cmp, event, helper) {
        
        var objChild = cmp.find('compB');
        alert("Method Called from Child " + objChild.get('v.myString'));
    }
})

ComponentB.cmp

<aura:component>
    <aura:attribute name="myString" type="String" access="public"/>
    <aura:attribute name="method" type="Aura.action"/>
    <lightning:button variant="brand" label="press" onclick="{!c.press}"/>
</aura:component>

ComponentB.js

({
    press : function(cmp, event, helper) {
        //set the child component value.
        cmp.set('v.myString','Hello World');
        var vx = cmp.get("v.method");
        //fire event from child and capture in parent
        $A.enqueueAction(vx);
    }
})