Skip to main content

Notifications

Finance | Project Operations, Human Resources, ...
Suggested answer

initializing object

(1) ShareShare
ReportReport
Posted on by 1,133
Hi,

if i have this constructor (newFromAandB) in a parent class
public class Parent
{
     private str a,b;

     public static Parent newFromAndB(str _a, str _b)
     {
        Parent parent = new Parent();
 
        parent.parmA(_a);
        parent.parmB(_b);

        return parent ;
     }

     public str parmA(str _a = a)
     {
        a = _a;
        return a;
     }

     public str parmB(str _b = b)
     {
        b = _b;
        return b;
     }
     
    private static Parent construct()
    {
        return new Parent();
    }

    protected void new()
    {
    }

    public void validate()
    {
        if( a == '')
        {
            throw error ("a should be filled");
        }
    }
}
 
then i have a child class that extends this class (but it doesn't need a new constructor)
public class Child extends Parent
{
    public void validate()
    {
        //Skip parent validation
    }
}
 

if I do this, then child will be empty
Child child = Parent::construct(a, b) as Child;

and i can't do this, because the new in the parent is protected and the child will still be empty anyway
Child child = new Child();
child = Parent::construct(a, b);

Is the only solution to define a constructor in the child class with exactly the same code as in the parent for it to work? can't  I utilize the parent class method?
public class Child extends Parent
{
     public static Child newFromAndB(str _a, str _b)
     {
        Child child = new Child();
 
        child.parmA(_a);
        child.parmB(_b);
 
        return child;
     }

    public void validate()
    {
        //Skip parent validation
    }
}
 

what would u do in this case in the construct method?
  • .. Profile Picture
    .. 1,133 on at
    initializing object
    Hi Martin,

    In this case I need to create a new enum and keep using newFromAAndB but add some logic to it

    So it will look like this, right? but the construct  of the child is private how to call it here as it's recommended by microsoft that the construct should be private
     
    public class Parent
    {     
         public static Parent newFromAndB(str _a, str _b, EnumType _enumType)
         {
            Parent parent;
            switch (_enumType)
            {
               case EnumType::Parent:
                  parent = Parent::Construct():
                  break;
               case EnumType::Child:
                  child = Child::Construct(): //how call it if it's private 
                  break;
            } 
    
            parent.parmA(_a);
            parent.parmB(_b);
    
            return parent ;
         }
    
         private static Parent construct()
         {
            return new Parent();
         }
    
         protected void new()
         {
         }
    
    }


    and the child will be like this (maybe i should add here the "constructor new" as protected as well?):
    public class Child extends Parent
    {
        public void validate()
        {
            //Skip parent validation
        }
        
        
        private static Child construct()
        {
            return new Child ();
        }
    
    }



     but what shall i call the method instead from newFromAandB? since it has an extra enumType?
     
    And When do you decide if you should use factory method or SysExtension or SysPlugin?

    And what is the best one?
  • Martin Dráb Profile Picture
    Martin Dráb 230,370 Most Valuable Professional on at
    initializing object
    Question: For option 2, do you mean to create a method in the parent class?
    Answer: Yes, the parent class is usually the most logical place. In more complex cases, a separate factor classed may be used instead.
     
    You'll see a plenty of examples in the standard application, e.g. SalesNonStockedValidator::newFromSalesLine():
    public static SalesNonStockedValidator newFromSalesLine(SalesLine _salesLine)
    {
        SalesNonStockedValidator salesNonStockedValidator;
    
        switch (_salesLine.SalesType)
        {
            case SalesType::Sales:
                salesNonStockedValidator = SalesNonStockedValidator::construct();
                break;
            case SalesType::ReturnItem:
                salesNonStockedValidator = SalesReturnNonStockedValidator::construct();
                break;
        }
        salesNonStockedValidator.parmSalesLine(_salesLine);
        salesNonStockedValidator.parmSalesPurchLine(_salesLine);
    
        return salesNonStockedValidator;
    }
     
    Question: So i should still leave the three methods in the parent class which are (new, construct and newFromAAndB) but also add another extra method?
    Answer: It depends on whether you want them for something or not. If the new method fully replaces construct() and newFromAAndB(), you can remove them. But you can, for example, call construct() from the new method (as shown above). new() is the constructor, not a method, and you need it if you want to change its default access modifier (which is likely) or run some initialization there.
  • .. Profile Picture
    .. 1,133 on at
    initializing object
    Hi Martin,

    For option 1, i agree, i shouldn't make the new public

    For option 2, do you mean to create a method in the parent class?
    So i should still leave the three methods in the parent class which are (new, construct and newFromAAndB) but also add another extra method?
    How would the method look like? and what is it's return type? do i need to create an interface/abstract class?


    For option 3, i will look at it if option 2 doesn't work
  • Suggested answer
    Martin Dráb Profile Picture
    Martin Dráb 230,370 Most Valuable Professional on at
    initializing object
    Let's start by getting the terminology right. newFromAndB() isn't a constructor, it's a static method (often called a factory method). Constructors are inherited, but static methods aren't (because they're associated with a particular class).
     
    If you want your Child class to have such a static method, you need to define it there.
     
    Of course, there are other options as well. For instance:
    • You could make the constructor (new()) public, but it's usually not recommended. For example, construct() method can be extended with CoC; constructors can't.
    • You could create a parametrized factory method that creates Parent or Child based on some criteria.
    • You could use SysPlugin or SysExtension frameworks to create an instance of the right object based on some criteria. It's mainly intended to allow adding more classes via extensions. See Register subclasses for factory methods for details.
    Of course that Parent::construct(a, b) as Child returns null. Parent::construct() creates a Parent instance, which can't be converted to Child.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

News and Announcements

Announcing Category Subscriptions!

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Verified Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,359 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,370 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans