According to documentation save method from Ext1 would be called in both situations.
(...) Overrides are defined by whichever methods are defined in the
“leftmost” extension, or, the extension that is first in the
comma-separated list. (...)
You can easily check it by yourself creating 3 classes and visualforce page, for example:
Class 1
public class TestCont1 {
private String myTxt = '1';
public String getMyTxt() {
return myTxt;
}
public void changeTxt() {
myTxt += '1';
}
}
Class 2
public class TestCont2 {
private String myTxt = '2';
public TestCont2(TestCont1 tc) {
}
public String getMyTxt() {
return myTxt;
}
public void changeTxt() {
myTxt += '2';
}
}
Class 3
public class TestCont3 {
private String myTxt = '3';
public TestCont3(TestCont1 tc) {
}
public String getMyTxt() {
return myTxt;
}
public void changeTxt() {
myTxt += '3';
}
}
And VF page:
<apex:page controller="TestCont1" extensions="TestCont2, TestCont3">
<apex:outputText value="{!myTxt}"/>
<apex:form>
<apex:commandButton action="{!changeTxt}" value="Change sth"/>
</apex:form>
</apex:page>
You will see on page that '2' is displayed and after each click on Change button '2' is added to the string.