Don't think of Virtual Outlets as outlets; think of them as boolean variables. If you are not a programmer, just think of them as telling you "true" or "false" (on or off, respectively). They allow you track the state of something. A good is example is using Virtual Outlets to track the health of a piece of equipment, we'll use heaters as an example:
Virtual Outlet Name: Htr1_Health
Set ON
If Output Heater_1 Watts < 175 Then OFF
If Output Heater_1 = OFF Then ON
Defer 003:00 Then OFF
What this does is create an outlet named "Htr1_Health" that remains "On" as long as the heater is in a "healthy" state, as defined by my criteria. In this case I have a 200w heater so I want to know if the wattage ever drops below 175 while the physical outlet is on (for at least 3 minutes), which would likely indicate that the heater is failing. I trigger my email alert if this outlet is ever in the "OFF" state. Think of "ON" as "Healthy" and "OFF" and "Unhealthy", in this case. I do this for both of my heaters.
Another example might be if you have a light that doesn't work directly with Apex but you want it to trigger behavior. In my case, I want my Fuge Light to come on when my AP700 is "off" (or in moon light mode).
Virtual Outlet Name: AP700_Status
Set OFF
If Output Light Watts > 10 Then ON
This virtual outlet lets me know the status of my AP700, as defined as being "ON" if it is drawing more than the moonlights typically do (10 watts). I then use this in the programming of my Fuge Light's physical outlet:
Physical Outlet Name: Fuge_Light
Fallback OFF
Set OFF
If Output AP700_Status = OFF Then ON
Defer 010:00 Then ON
Defer 010:00 Then OFF
This causes the Fuge Light to go on or off after the AP700 status has been changed for at least 10 minutes.
The reason they are used is that they allow you to do more advanced behavior than is possible by just using the physical outlet's programming alone. It also increases readability which, for any of the programmers here, is of the utmost importance in programming. It is much easier to read: "If AP700_Status = OFF" inside my Fuge Light outlet code than injecting the virtual outlet's code directly. It is essentially delegation: I created a virtual outlet that I know works always and tells me my AP700's status: I never need to think of it again and I can use that Virtual Outlet in many different places without having to duplicate code. If I ever want to change the behavior of tracking the AP700's status (like maybe changing the "ON" trigger to > 15w instead), then I do it in one place: not a bunch of separate places. Same goes for my heater health states: I can rely on those virtual outlets as always working and not have to think about that behavior again, and focus on programming any other behaviors around their states. I think my examples demonstrate these ideas, but if not let me know and I'll try to better explain.
I hope this helps!
EDIT: Also, the Virtual Outlets can be used to create more complex conditional statements. Any single outlet can really only track a single "ON" and "OFF" state, but if you layer various Virtual Outlets together, you can effectively end up with "AND" statements. It's not an ideal way for Apex to have done it, but it's the way it is... They don't have a simple "AND" statement unfortunately. Allow me to give an example. Let's say I want to have a behavior only if both my AP700 is ON and my heater 1 health is bad (this is just an example, bear with me). There is no way to write in an outlet: If AP700_Status = ON AND Htr1_Health = OFF... BUT, I can create a third virtual outlet:
Virtual Outlet Name: LGHT_ON_BAD_HTR
Set OFF
If Htr1_Health OFF Then ON
If AP700_Status OFF Then OFF
Now, in whatever outlet I want to use that information to trigger a behavior I can just say:
If LGHT_ON_BAD_HTR = ON Then OFF
This effectively created the "AND" statement that I wasn't able to directly write before.