Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

When exactly should we use inner classes as opposed to separating class out.Largely discussed use case is for wrapper class for eg:

public class WrapperDemoController{
    /*Our Wrapper Class
    public class TableRow{
        public String Name      {get;set;}
        public String Phone     {get;set;}
        public String Company   {get;set;}
    }*/

    /*Public Property that will hold all the TableRows and our PageBlockTable can use this Variable   to get the whole List of rows*/
    public List<TableRow> RowList {get; set;}

    /*Constructor that runs a SOQL to get all the Records and build the List. This get executed automatically on the Page Load.*/
    public WrapperDemoController(){

        RowList = new List<TableRow>();
        TableRow tr;

        /*Building the List of TableRows*/
        /*Fetch all the Contacts and then build the List*/
        for(Contact con : [SELECT Name, Phone, Account.Name FROM Contact]){

            tr = new TableRow();
            tr.Name = con.Name;
            tr.Phone = con.Phone;
            tr.Company = con.Account.Name;

            /*Add the TableRow to the List then and there*/
            RowList.add(tr);
        }
    }
}

In above code i have commented out wrapper class and created a separate class by copying same code.and code works the same..so whats is the driving factor to decide whether things should be in innerclass/or separate?

share|improve this question
    
There are two good answers that explain why, but my preference is to avoid inner classes whenever possible (in any language). I find it clutters the code too much. The only time I will consider it is if the class is used only within the outer class and not referenced anywhere else. –  John Gaughan Jun 19 at 13:28
add comment

2 Answers 2

I think it largely depends on how complex the inner class is and if the inner class needs to be reused anywhere. The example you provided is fairly simple and only serves to hold data, so I think it this is a valid case for an inner class. If that inner class had more logic in it, then that's when you should consider making it it's own class.

As for reuse, I generally start with an inner class and pull the class out when I need to reuse it; it's easier to move an inner class out than the other way around since you don't need to change any of the references in the parent class (though you would still need to change any test references).

Edit: Example of pulling out an inner class:

Original: public class MyParentClass { MyInnerClass innerInstance;

    public MyParentClass()
    {
        this.innerInstance = new MyInnerClass();
    }
    public class MyInnerClass
    {
    }
}

Inner Class Moved Out:

Parent Class File:

public class MyParentClass
{
    MyInnerClass innerInstance;

    public MyParentClass()
    {
        this.innerInstance = new MyInnerClass();
    }
}

Inner Class in Separate File

public class MyInnerClass
{
}

When MyInnerClass was moved into its own file, I didn't have to change any of the references to MyInnerClass in the original Parent Class file.

share|improve this answer
    
what do you mean by 'you don't need to change any of the references in the parent class'.. –  sfdc99999 Jun 18 at 14:36
    
I edited the original answer with an example –  Sean Jun 18 at 15:09
2  
It's more a matter of aesthetics, I agree, but it's generally better to split the class into its own if either condition is met: your main class is approaching the upper size limit (1,000,000 characters), or the functionality is useful in multiple classes. –  sfdcfox Jun 18 at 15:15
add comment

Most of the time the threshold is aesthetic, as sfdcfox notes. If nobody cares (except tests) about it outside of the parent definition, definitely use an inner class to avoid the clutter and associated mental overhead.

I can think of a couple good use cases:

  1. For Exception subclasses that are only relevant inside the class:

    public with sharing class UserFinder {
    
        public class UserNotFoundException extends Exception {}
    
    }
    
  2. To evade security review, where inner classes are not scanned:

    public WITH sharing class LimitedDataManipulator {
    
        public void naughtyStuff() {
            new UnlimitedDataManipulator().doNaughtyStuff();
        }
    
        WITHOUT sharing class UnlimitedDataManipulator {
            public void doNaughtyStuff() {
                //naughty stuff here
            }
        }
    }
    
  3. To define parameter types only relevant inside the class:

    public with sharing class EmailBlaster {
    
        class Spam {
            public Id UserId;
            public String SalesCopy;
        }
    
        public void sendSpams(List<Spam> spams) {
            //email each user
        }
    }
    
  4. To supply test implementations in test classes

    @IsTest public class AbstractThingTest {
    
        class FakeImpl extends AbstractThing {
            //...
        }
    
        static testmethod void testFakeImplWorksOk() {
            new FakeImpl(); //...
        }
    
    }
    

And maybe are a few caveats:

  • inner classes cannot have static members (so no @Future annotations etc)
  • inner classes cannot be global unless the outer class is also global
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.