Domain 4 β€” Module 2 of 6 33%
12 of 28 overall
Domain 4: Develop and Test Code Free ⏱ ~15 min read

Object-Oriented X++: Inheritance & Interfaces

Classes, inheritance, abstract classes, interfaces, variable scoping, QueryBuilder, and attributes in X++.

Object-Oriented X++: Inheritance & Interfaces

Simple explanation

OOP in X++ works like C# or Java. Classes are blueprints. Inheritance lets children get parent features. Abstract classes cannot be built directly. Interfaces define contracts. QueryBuilder creates dynamic database queries at runtime.

Classes

public class CustomerValidator
{
    private str accountNumber;
    public void new(str _acct) { accountNumber = _acct; }
    public boolean validate()
    {
        CustTable ct;
        select firstOnly ct where ct.AccountNum == accountNumber;
        return (ct.RecId != 0);
    }
    public static CustomerValidator construct(str _acct) { return new CustomerValidator(_acct); }
}

Variable Scoping

ScopeLifetime
Class memberObject lifetime
Method localUntil method returns
Block localUntil block ends

πŸŽ“ Sophie: β€œCarl says keep scope tight β€” declare variables where they are used.”

Inheritance

public class InvoiceProcessor extends DocumentProcessor
{
    public void new(real _amount) { super(); }
    public void process() { super(); info("Invoice processed"); }
}

extends = inheritance, super() = call parent, single inheritance only.

Abstract Classes and Interfaces

public abstract class PaymentBase
{
    public abstract boolean processPayment(real _amount);
}

public interface IExportable { str exportToJson(); }

public class SalesOrder extends PaymentBase implements IExportable
{
    public boolean processPayment(real _amount) { return true; }
    public str exportToJson() { return "..."; }
}
Abstract Class vs Interface
FeatureAbstract ClassInterface
Method bodiesMix abstract/concreteAll abstract
StateYesNo
InheritanceSingleMultiple
Use whenShared base behaviourContract across classes

QueryBuilder

Query query = new Query();
QueryBuildDataSource qbds = query.addDataSource(tableNum(CustTable));
qbds.addRange(fieldNum(CustTable, CustGroup)).value("10");
qbds.addSortField(fieldNum(CustTable, Name), SortOrder::Ascending);
QueryRun qr = new QueryRun(query);
while (qr.next())
{
    CustTable ct = qr.get(tableNum(CustTable));
    info(ct.Name);
}
select vs QueryBuilder
Static selectQueryBuilder
WhenCompile-time fixedRuntime dynamic
FormsNot for form DSUsed by forms
UseLookups, logicReports, dynamic filters

Attributes

AttributePurpose
[DataContractAttribute]Serializable class
[DataMemberAttribute]Include in contract
[SysEntryPointAttribute]Service entry point
[ExtensionOf]CoC extension
[DataContractAttribute]
public class ReportContract
{
    private date fromDate;
    [DataMemberAttribute]
    public date parmFromDate(date _v = fromDate) { fromDate = _v; return fromDate; }
}

πŸ‘¨β€πŸ’» Elena: β€œThe parm pattern β€” pass a value to set, call empty to get. Every data contract uses it.”

Question

extends vs implements?

Click or press Enter to reveal answer

Answer

extends = one parent (inheritance). implements = interface contract (multiple ok).

Click to flip back

Question

super() does what?

Click or press Enter to reveal answer

Answer

Calls parent class version of current method.

Click to flip back

Question

QueryBuilder vs select?

Click or press Enter to reveal answer

Answer

QueryBuilder for runtime dynamic queries. select for compile-time fixed.

Click to flip back

Question

[DataContractAttribute] purpose?

Click or press Enter to reveal answer

Answer

Marks class for serialization. Used with SysOperation. Properties opt in via [DataMemberAttribute].

Click to flip back

Knowledge Check

Marcus needs a serializable request class. Attributes?

Knowledge Check

Dynamic filters based on user input?


Next up: Chain of Command β€” the most important extensibility pattern.