Let's say I have two classes called "SuperClass" and SubClass. SubClass extends SuperClass.
I just found out that it's not possible for SuperClass to have an instance variable of type SubClass.
That is, this will not work:
class SuperClass{
SubClass x = new SubClass();
}
because it causes the constructors to call each other, entering a perpetual loop. (because Java automatically puts in the call to Super())
Is creating a subclass instance variable impossible and a bad design idea? or is there some kind of work-around?
It is generally a bad idea. If your super class needs an instance of a subclass, that's a code smell. It creates circular dependencies and suggests a broken analysis.
The workaround/fix is usually to bring up whatever code the super class is using from the subclass into the super class.
The only restriction is in placing an allocation of the subclass (or, for that matter, another instance of the superclass) within the superclass constructor. You can most certainly have an instance field with the type of a subclass, and set it at some point after construction of the superclass. (Though you would obviously need to prevent any recursion via the setter method.)
And actually one could put the allocation in the superclass constructor if there were conditional logic in the constructor to skip the allocation if constructing the subclass. Eg:
class SuperClass {
SubClass subClassField;
SuperClass() {
if (!(this instanceof SubClass)) {
subClassField = new SubClass();
}
}
}
But, of course, just because you can do this does not say that you should. While I can imagine a few scenarios where it might be a valid approach, they would be "oddball" situations.
Related
I fully understand that a System.Array is immutable.
Given that, why does it have an Add() method?
It does not appear in the output of Get-Member.
$a = #('now', 'then')
$a.Add('whatever')
Yes, I know this fails and I know why it fails. I am not asking for suggestions to use [System.Collections.ArrayList] or [System.Collections.Generic.List[object]].
[System.Array] implements [System.Collections.IList], and the latter has an .Add() method.
That Array implements IList, which is an interface that also covers resizable collections, may be surprising - it sounds like there are historical reasons for it[1]
.
In C#, this surprise is hard to stumble upon, because you need to explicitly cast to IList or use an IList-typed variable in order to even access the .Add() method.
By contrast, since version 3, PowerShell surfaces even a type's explicit interface implementations as direct members of a given type's instance. (Explicit interface implementations are those referencing the interface explicitly in their implementation, such as IList.Add() rather than just .Add(); explicit interface implementations are not a direct part of the implementing type's public interface, which is why C# requires a cast / interface-typed variable to access them).
As a byproduct of this design, in PowerShell the .Add() method can be called directly on System.Array instances, which makes it easier to stumble upon the problem, because you may not realize that you're invoking an interface method. In the case of an array, the IList.Add() implementation (rightfully) throws an exception stating that Collection was of a fixed size; the latter is an exception of type NotSupportedException, which is how types implementing an interface are expected to report non-support for parts of an interface.
What helps is that the Get-Member cmdlet and even just referencing a method without invoking it - simply by omitting () - allow you to inspect a method to determine whether it is native to the type or an interface implementation:
PS> (1, 2).Add # Inspect the definition of a sample array's .Add() method
OverloadDefinitions
-------------------
int IList.Add(System.Object value)
As you can see, the output reveals that the .Add() method belongs to the Ilist interface.
[1] Optional reading: Collection-related interfaces in .NET with respect to mutability
Disclaimer: This is not my area of expertise. If my explanation is incorrect / can stand improvement, do tell us.
The root of the hierarchy of collection-related interfaces is ICollection (non-generic, since v1) and ICollection<T> (generic, since v2).
(They in turn implement IEnumerable / IEnumerable<T>, whose only member is the .GetEnumerator() method.)
While the non-generic ICollection interface commendably makes no assumptions about a collection's mutability, its generic counterpart (ICollection<T>) unfortunately does - it includes methods for modifying the collection (the docs even state the interface's purpose as "to manipulate generic collections" (emphasis added)). In the non-generic v1 world, the same had happened, just one level below: the non-generic IList includes collection-modifying methods.
By including mutation methods in these interfaces, even read-only/fixed-size lists/collections (those whose number and sequence of elements cannot be changed, but their element values may) and fully immutable lists/collections (those that additionally don't allow changing their elements' values) were forced to implement the mutating methods, while indicating non-support for them with NotSupportedException exceptions.
While read-only collection implementations have existed since v1.1 (e.g, ReadOnlyCollectionBase), in terms of interfaces it wasn't until .NET v4.5 that IReadOnlyCollection<T> and IImmutableList<T> were introduced (with the latter, along with all types in the System.Collections.Immutable namespace, only available as a downloadable NuGet package).
However, since interfaces that derive from (implement) other interfaces can never exclude members, neither IReadOnlyCollection<T> nor IImmutableCollection<T> can derive from ICollection<T> and must therefore derive directly from the shared root of enumerables, IEnumerable<T>.
Similarly, more specialized interfaces such as IReadOnlyList<T> that implement IReadOnlyCollection<T> can therefore not implement IList<T> and ICollection<T>.
More fundamentally, starting with a clean slate would offer the following solution, which reverses the current logic:
Make the major collection interfaces mutation-agnostic, which means:
They should neither offer mutation methods,
nor should they make any guarantees with respect to immutability.
Create sub-interfaces that:
add members depending on the specific level of mutability.
make immutability guarantees, if needed.
Using the example of ICollection and IList, we'd get the following interface hierarchy:
IEnumerable<T> # has only a .GetEnumerator() method
ICollection<T> # adds a .Count property (only)
IResizableCollection<T> # adds .Add/Clear/Remove() methods
IList<T> # adds read-only indexed access
IListMutableElements<T> # adds writeable indexed access
IResizableList<T> # must also implement IResizableCollection<T>
IResizableListMutableElements<T> # adds writeable indexed access
IImmutableList<T> # guarantees immutability
Note: Only the salient methods/properties are mentioned in the comments above.
Note that these new ICollection<T> and IList<T> interfaces would offer no mutation methods (no .Add() methods, ..., no assignable indexing).
IImmutableList<T> would differ from IList<T> by guaranteeing full immutability (and, as currently, offer mutation-of-a-copy-only methods).
System.Array could then safely and fully implement IList<T>, without consumers of the interface having to worry about NotSupportedExceptions.
To "Add" to #mklement0's answer: [System.Array] implements [System.Collections.IList] which specifies an Add() method.
But to answer why have an Add() if it doesn't work? Well, we haven't looked at the other properties, i.e. IsFixedSize :
PS > $a = #('now', 'then')
PS > $a.IsFixedSize
True
So, a [System.Array] is just a [System.Collections.IList] that is a Fixed Size. When we look back at the Add() method, it explicitly defines that if the List is Read-Only or Fixed Size, throw NotSupportedException which it does.
I believe the essence is not, "Let's have a function that just throws an error message for no reason", or to expand on it, No other reason than to fulfill an Interface, but it actually is providing a warning that you are legitimately doing something that you shouldn't do.
It's the typical Interface ideas, you can have an IAnimal type, with an GetLeg() method. This method would be used 90% of all animals, which makes it a good reason for implementing into the base Interface, but would throw an error when you use it against a Snake object because you didn't first check the .HasFeet property first.
The Add() method is a really good method for a List Interface, because it is an essential method for Non-Readonly and Non-Fixed length lists. We are the ones being stupid by not checking that the list is not IsFixedSize before calling an Add() method that would not work. i.e. this falls into the category of $null checks before trying to use things.
For Example,
We could just use
onClick={(foo)}
or something else.. instead of
onClick={this.foo.bind(this)}
Just curious if there is any particular technical constraint.
Let me answer the question from a design/philosophical perspective, instead of a technical one (the other answers do that pretty well already).
React COULD have, there would be no problem to that. But why have multiple ways to do things when you can have one (React tries to stay as close to ES standards as possible). If there are multiple ways to do a single task, it'll affect readability across codebases, making it harder for developers to ease into a codebase since they would have to unravel layers upon layers of abstraction till they gets to the core idea.
Basically, I think it was a design choice to NOT add a lot of the syntactic sugar that could have been added (JSX itself is already a form of syntactic sugar, we don't need syntactic sugar on our syntactic sugar).
From the React Docs:
"In general we resist adding features that can be implemented in userland. We don't want to bloat your apps with useless library code. However, there are exceptions to this."
"We prefer boring code to clever code. Code is disposable and often changes. So it is important that it doesn't introduce new internal abstractions unless absolutely necessary."
Source: https://facebook.github.io/react/contributing/design-principles.html
Representing the ideas from this talk: https://www.youtube.com/watch?v=4anAwXYqLG8
onClick={foo} is something completely different to onClick={this.foo.bind(this)}, and parentheses are required for maths.
.bind causes a new function to be created on every single invocation, so this would not be very performant.
(I assume) an aim of JSX to try and be as close to regular JS as possible so it's easy to pick up.
It is not the realm of JSX to add new language elements; a bind operator is most definitely a new language element.
If you notice, JSX doesn't provide any new language constructs other than what is necessary to call React.createElement. Additionally, you probably wouldn't want to use .bind like this anyway due to fact it's creating a new function every time. Finally, the parens are required for mathematical operations - you couldn't use {()} because what if I wanted to use a mathematical operation like {(a + b) * c}? Any interpolation that JSX does must be a JavaScript expression, currently, so unless JavaScript itself supports this syntax it's unlikely the interpolation will too.
You may be interested in the function bind operator, but I'd recommend you avoid using bind in this manner; instead, bind the functions once in the component constructor, like so:
class MyComponent extends Component {
constructor() {
this.boundOnClick = this.onClick.bind(this)
}
render() {
return <button onClick={this.boundOnClick}>Foo</button>
}
}
// with function bind operator
class MyComponent extends Component {
constructor() {
this.boundOnClick = ::this.onClick
}
render() {
return <button onClick={this.boundOnClick}>Foo</button>
}
}
This ensures you only create the bound function once. For stateless components, you don't have access to this anyway so there's no need to use bind.
If JSX were to introduce an alternative syntax to this, I personally would be opposed to it, though if they could overcome the limitations I've mentioned above, there's nothing technically stopping them.
It is more a problem with ES6 which does not have automatic binding of "this" to class methods. In ES7, there is a proposal to introduce a new operator ::. With ES7, you could write:
onClick={this::foo}
class MyClass : public CObject
{
public:
MyClass();
private:
CStringArray m_myArray;
};
causes error c2248
What's wrong with this ?
I think it's related to the fact that CStringArray and MyClass both derive from CObject.
Legacy class derived from CObject currently uses CustomArray it just seems wrong to me so I would like to replace it by CStringArray.
Microsoft compiler error C2248 means "Members of a derived class cannot access private members of a base class."
I can only assume you're trying to directly reference MyClass::m_myArray from somewhere in your code, without using a public accessor function.
Update
The real answer is that the problem is caused by the copy-constructor for MyClass, attempting to copy m_myArray, but it can't, because CObject derived classes aren't copyable by default. The solution would be to write a copy constructor yourself, and rather than attempt to copy the array, copy the contents one at a time, from the source array to the destination array. Either that or use std::vector (which you should be doing anyway, as MFC containers are horrible).
You are trying to access some private member of CObject. Since both your MyClass and CStringArray derive from CObject, without more context it is impossible to know the exact problem.
The only idea that comes to mind, basically because I've fallen in the trap many times, is that CObject's copy constructor is private, so if you are trying to copy either the CStringArray or your own class, explicit or implicitly, you'll get the error.
UPDATE:
I've just taken a look at CObject's declaration and the assignment operator, too, is private. Everything else is either public or protected.
Error C2248 says "Members of a derived class cannot access private members of a base class."
CStringArray class dosn't expose Copy constructor and assignment operator, look in code for such places and replace the code with elemenet by elemnet copy.
I have created an array in the implementation of my class loginController. Now I want to use this array (with its objects) in another class of my project. What is the right way to import it?
You really need to specify the language.
In general, if the array is a member variable in one class, it's considered bad form to directly use it from another class. This violates the "encapsulation" idea that is quite the thing in object-oriented programming.
The preferred thing to do is often to add methods, called "getters" and "setters", to the class owning the array, or make it available by some other more structural means, which depend on the exact semantics and usage of the array. It might, for instance, not be required that outside users even know that it is an array.
There is no right way given this information. What is located in the array, only integers or strings/objects etc. Do you store objects of pointers to objects?
Passing the array is the sameway as passing any other object to a function
The general answer would be: declare it as public
It is not very good thing to do but as a beginner, you can start with that.
The problem domain features a large population of named snarks. Some of the snarks are boojums.
There are at least two ways to model this:
// as a property:
class Snark {
string name;
bool is_boojum;
};
// as a list:
class Snark {
typedef long Id;
Id id;
string name;
};
tree<Snark::Id> boojums;
It seems intuitive that if we determined that snarks come in male and female, we would add a "sex" property to the snark class definition; and if we determined that all but five snarks were vanquished subjects, we would make a list of royals.
Are there principles one can apply, or is it a matter of architectural preference?
What problem are you trying to solve?
If the purpose of recording the royalty of the snarks is to display a crown on their heads in the GUI, then it makes sense for it to merely be an attribute. (Alternatively, there could be a RoyalSnark subclass, with an overridden Render method.)
If the purpose is to quickly find all the royal snarks, then a list is more appropriate - otherwise you would need to look at every snark and check its attribute.
I believe that the information entropy associated with the classification can be a guide to which method to use. Low-entropy classifications (i.e. most of the objects have the same value) suggest a list implementation tracking the exceptional cases, while high-entropy classifications (you cannot make any very good predictions about which classification an object will have) suggest a property implementation.
As a derived class:
class Snark
{
virtual void Approach(Creature& approacher) {};
};
class Boojum : public Snark
{
virtual void Approach(Creature& approacher)
{
approacher.softlySuddenlyVanishAway();
}
};
That natural way to do it seems to be a property in all cases.
You might use a list for performance, or to optimise space. Both reasons strike me as potential cases of premature optimisation, breaking encapsulation, and/or storing redundant data with the consequent risk of lack of integrity (because I should still be able to query the object itself to find out if it is royal - I shouldn't have to know that this property is handled in a special way for reasons of performance). You could I suppose hide the list implementation behind a getter, to make it behave as a property.
Also, if these objects were stored in a DB, the performance issue pretty much goes away as the DB layer can create the list at runtime using a query anyway.
If you're asking about database modeling, then it's most straightforward to treat is_boojum as an attribute column in the table Snarks. If you need to search for all boojums, the query is simple:
SELECT * FROM Snarks WHERE is_boojum = 1
This gives logically correct answers, and it's easy to model. It might not be so speedy, because indexing a column with low selectivity (many rows with identical values) isn't very efficient, and might not benefit from the index at all.
But your question was about modeling, not optimization.
Hmmm. My first thought is that, indeed, Boojum is a subtype of Snark. but the specification seems to argue against it, for "the snark was a boojum, you see." Well, that means the snark is_a Boojum, and that would make the inheritance graph cyclic. Can't have that.
On the other hand, I do'nt think there's any indication that a Snark can become a Boojum; either it's a Boojum or it's not.
I think probably you want a Boojum mixin --
abstract class Snark { /*...*/ };
class PlainSnark extends Snark {/*...*/};
class RoyalSnark extends Snark implements Boojum {/*...*/};