Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It's not clear to me from your question whether or not you already know VBA and/or OO, and are just asking how to use the object-oriented features of VBA. If you are new to both VBA and OO, see below for some thoughts on why VBA isn't a very good vehicle for learning OOD/OOP.</p> <p>To address the general part of your question, VBA classes <em>can</em> implement interfaces. This is how you express <em>inheritance of interface</em> (an "is-a" relationship) in VBA. There is no direct way to express <em>inheritance of implementation</em> in VBA. Instead, to make one class inherit the implementation of another, you have the first implement the interface of the second, contain an instance of the second, and then delegate calls to that instance. See this answer for more:</p> <p><a href="https://stackoverflow.com/questions/3669270/vba-inheritance-analog-of-super/3671434#3671434">VBA inheritance, analog of super</a></p> <p>There is a link there, that I will repeat here, to the Visual Studio 6.0 Programmer's Guide:</p> <p><a href="http://msdn.microsoft.com/en-us/library/aa240846(v=VS.60).aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/aa240846(v=VS.60).aspx</a></p> <p>It's as good a short introduction as any on the "VBA way" of OOP (although it's written for VB6, not VBA).</p> <hr> <p>Now, for your specific question about design: "how for the contained object to collect its inputs, which are only available in the container objects".</p> <p>You need to think about what you are actually modeling here. Regardless of how you implement it, a "speed calculator" should only get to know about a very specific set of inputs, not the entire internal state of whatever vehicle is using it. In VBA, as you note, there are no static classes. Instead, use a regular code module and have a function that you call from inside your vehicle class(es):</p> <pre><code>Public Function calcSpeed(temp, windspeed, rpm) 'do calc based only on parms passed in... End Function </code></pre> <p>If it needs to take a zillion parameters because that's how the calculation works, so be it. Don't try to hide it. Of course, you can wrap them up in a <code>Type</code> or in a class if there are too many.</p> <p>Now, does every different kind of vehicle calculate speed in the exact same way from the exact same set of state parameters? If so, then have a <code>speed</code> property or method that is implemented by your "base vehicle" class and call <code>calcSpeed</code> from there. </p> <p>But maybe it's the case that different kinds of vehicles have different state parameters, or use different calculation methods, or the calculation is the same but not every vechicle type supplies every parameter. In that case, put the <code>speed</code> method in the base vehicle <em>interface</em>, but "override" it as needed in the implementation of each subclass. (Maybe then <code>calcSpeed</code> is too simplistic, and you'd end up with a library of speed calculation helper functions.)</p> <p>One thing I would <em>not</em> do, is have a generic SpeedCalculator class that takes a Vehicle argument and then interrogates it for its state in order to do the calc. The reason why not is expressed very well in these classic articles:</p> <p><a href="http://media.pragprog.com/articles/may_04_oo1.pdf" rel="nofollow noreferrer">http://media.pragprog.com/articles/may_04_oo1.pdf</a></p> <p><a href="http://pragprog.com/articles/tell-dont-ask" rel="nofollow noreferrer">http://pragprog.com/articles/tell-dont-ask</a></p> <p><a href="http://www.cmcrossroads.com/bradapp/docs/demeter-intro.html" rel="nofollow noreferrer">http://www.cmcrossroads.com/bradapp/docs/demeter-intro.html</a></p> <p>There's also this:</p> <p><a href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf" rel="nofollow noreferrer">http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf</a></p> <p>which has a quote I like:</p> <blockquote> <p>So, what's so bad about this code (besides being a horribly contrived example)? Well, lets translate what the code is actually doing into real-language: </p> <p>Apparently, when the paperboy stops by and demands payment, the customer is just going to turn around, let the paperboy take the wallet out of his back pocket, and take out two bucks.</p> <p>I don't know about you, but I rarely let someone handle my wallet. There are a number of 'realworld' problems with this, not to mention we are trusting the paperboy to be honest and just take out what he's owed. If our future Wallet object holds credit cards, the paperboy has access to those too... but the basic problem is that “the paperboy is being exposed to more information than he needs to be”. </p> <p>Thats an important concept... The 'Paperboy' class now 'knows' that the customer has a wallet, and can manipulate it. When we compile the Paperboy class, it will need the Customer class and the Wallet class. These three classes are now 'tightly coupled'. If we change the Wallet class, we may have to make changes to both of the other classes.</p> </blockquote> <p>ADDED AS PROMISED IN COMMENTS:</p> <p>It's not that you couldn't readily have an instance of a class <code>Speedometer</code> contained within your <code>Vehicle</code>s. (My example of a simple function might be too simplistic. Maybe you need a class to model the other things about speedometers - they have mass, take up space, etc.) It's how the two classes depend on each other. In this example, <code>Vehicle</code> needs to know about <code>Speedometer</code>. But why should the reverse be true? If <code>Speedometer</code> takes a <code>Vehicle</code> as a parameter, and then asks it for the particular things it needs to know to calculate speed, the code will certainly <em>work</em>. However, you've coupled <code>Speedometer</code> to <code>Vehicle</code> more tightly than necessary.</p> <p>One of the reasons to use an OO approach in the first place is because it lets you be more exact about how concepts relate to each other. It's better to have <code>Vehicle</code> tell <code>Speedometer</code>, "Here are some facts about the world. Give me back a speed.", rather than, "Here I am, <code>Me</code>, the <code>Vehicle</code> that contians you. Ask me whatever you need to about anything related to me, and then give me back a speed." (Note that whether the "facts about the world" are raw temp, windspeed, etc., or an instance of some <code>SpeedometerInput</code> Type/Class isn't the issue. It's that speedometers don't need to know all about vehicles.)</p> <p>Using the most exact interface you can get away with doesn't make that big of a deal in a simple example. But it becomes huge when added up over many design decisions. </p> <hr> <p>Finally, If you have a choice, I <em>wouldn't</em> use VBA as a vehicle for learning object-oriented design or programming. You can do "OOP" in VBA, but in a Microsoft-/COM-specific way that is literally a relic from the mid-1990s. You can browse around stackoverflow for plenty of examples of things that are normally done in OO programming languages (and with their much better libraries) that are cumbersome and tricky in VBA. Here are a few off the top of my head that I've either asked or answered:</p> <p><a href="https://stackoverflow.com/questions/1731052/is-there-a-way-to-overload-the-constructor-initialize-procedure-for-a-class-in">Is there a way to overload the constructor / initialize procedure for a class in VBA?</a></p> <p><a href="https://stackoverflow.com/questions/4487521/is-there-a-way-to-write-an-equality-test-for-a-vba-class-with-private-members-wit">Is there a way to write an equality test for a VBA class with private members without exposing knowledge of the existence of those private members?</a></p> <p><a href="https://stackoverflow.com/questions/5695977/restrict-type-in-a-collection-inside-a-class-module">Restrict type in a Collection inside a class module</a></p> <p><a href="https://stackoverflow.com/questions/4749698/excel-vba-is-there-anything-like-javas-set-container-in-vba">Excel-VBA - Is there anything like Javas Set container in VBA?</a></p> <p>So, unless you're either constrained to learn with VBA because you can't install anything but MS Office on your machine, or you plan to be doing a lot of VBA work becuase you're <em>using</em> Excel, Access, etc. and have some problems where OOP can help, I'd look elsewhere. <a href="http://www.python.org/" rel="nofollow noreferrer">Python</a>, <a href="http://www.microsoft.com/express/Windows/" rel="nofollow noreferrer">.NET</a>, or <a href="http://www.java.com/en/" rel="nofollow noreferrer">Java</a> are all available for free on Windows and have tons of resources available for the beginner.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload