I'm new to object-oriented-programming, and I have set a strict goal for myself for my current project which is not using static variables. In the process I will try to learn about OOP.
I'm using the Haxe language and it's one of the best languages I've ever seen.
I know a bit about C pointers, and that pointers only store the address of a variable so its pretty much the same variable, just taking up less space (especially for large variables).
Now back to the present, I want to have pointer references to an array of objects of one class because
I want these objects to interact with each other,
and I don't want to have any static references,
and I don't want to have every object holding a copy of that array.
How should I go along accessing this array?
Or is there another OOP design pattern or something?
Please correct me if I got something wrong.
There are many questions in this brief.
You can just pass along a context along all your variables, it will be passed by pointer
class Context{
var level:Level=null;
var enemies:Array<Enemy>=[];
}
class Enemy{
var ctx:Context;
function new(ctx){ this.ctx=ctx; }
}
class Main{
static function main(){
new Game(new Context());
}
}
and in game, pass along the context to everyone :
new Enemy(ctx);
etc...
Frankly it is often easier to use static for contexts, like
class Context{
static var level:Level;
}
But that's up to you :)
As a side note, all non primitives are pointers to structure (ex arrays) just like java.
Related
I have a query regarding a concept.
Are dynamic arrays in c# also called list? Or they are totally different?
C# does not have a dynamic array type. However, you can use a List as a dynamic array, given that it supports indexed access:
List<string> list = new List<string>();
list.Add("Hello");
list.Add("Goodbye");
Console.WriteLine(list[1]);
Take a look at Generic Lists.
Since it's the first link I found out when looking for this difference I would like to contribute a little.
The Nitin Bisht response is not entirely wrong, but by most of programming definitions a dynamic array is a type of array that can be set when the program is already running, simply put, it's size is set during run time not in compilation.
In C# this is written as:
string[] myDynamicArray;
myDynamicArray = SomeMethodThatReturnsAnCollection().ToArray();
Other way would be a method which returns an existing array like:
string[] myDynamicArray;
myDynamicArray = SomeMethodThatReturnsAnArray();
Those are Dynamic Arrays, you don't tell your program which size it has but inside the logic of that context this will be decided.
Those Arrays in C# has the Resize method, which enables the programmer to grow the array, which I believe it was the Nitin Bisht and so many others interpretation around that question, but this is a wrong assumption, resizable is different than dynamic.
Instead of using Resize in your Array, you could just use a List type, List in C# implements an Array in it's core, which can be seen here, but it also has the ability to grow in an easier approach than the Array implementation enables us with the Add(T item) List method.
List in C# would be a native Dynamic Resizable Array, some languages call similarly implementations of this structure as Vector, which are not a LinkedList with nodes and pointers for example.
Summarizing the difference in code:
var myList = new List<string> { "initial value" };
myList.Add("New value"); // After add, myList has this new value
var myArray = new string[] { "initial value" };
myArray.Append("New value") // after Append myArray doesnt have a new value
With Append() method what happens is another IEnumerable collection is created with the new value, so if you iterate through both collections you will see that the list prints out the new value but the array doesn't, in that case one way you can fix that is doing this:
string[] myArray;
myArray = myArray.Append("New value").ToArray(); // now it will work
The difference here is that myArray variable is being rewritten with the new array generated by .Append().ToArray() line, in the List example the Add() method will resize and then add the new value.
Important to note that this resize is done in a similar manner than what we did with the Append() "fixed" code, the List creates a new Array with increased size and copies it's original contents to this new Array.
You can use the resources given by the Array class to get to the same result as the Add() method implemented by List, but off course if you need that method you should just use an List instead of writing your own implementation, very rarely you would have to do it and to be honest your implementation would be probably less efficient than the already built ones.
In summary that is the difference between them, as you can see they have similarities but I would still treat them very differently.
Usually you wanna use an array when you do not expect to grow any further, if that is your case then an array is more useful since it's has less implementations and that brings a performance gain which can be good in a lot of scenarios.
If not, just use lists.
Say I wanted to store objects statically inside their own class. Like this:
public class Foo
{
private static int instance_id = 0;
public static List<Foo> instances = new List<Foo>();
public Foo()
{
instances[instance_id++] = this;
}
}
Why?
I don't need to create unique array structures outside the class (one will do).
I want to map each object to a unique id according to their time of birth.
I will only have one thread with the class in use. Foo will only exist as one set in the program.
I did searching, but could find no mention of this data structure. Is this bad practice? If so, why? Thank you.
{please note, this question is not specific to any language}
There are a couple of potential problems I can see with this setup.
First, since you only have a single array of objects, if you need to update the code so that you have lots of different groups of objects in different contexts, you'll need to do a significant rewrite so that each object ends up getting associated with a different context. Depending on your setup this may not be a problem, but I suspect that in the long term this decision may come back to haunt you.
Second, this approach assumes that you never need to dispose of any objects. Imagine that you want to update your code so that you do a number of different simulations and aggregate the results. If you do this, then you'll end up having your giant array storing pointers to objects you're not using. This means that you'll (1) have a memory leak and (2) have to update all your looping code to skip over objects you no longer care about.
Third, this approach makes it the responsibility of the class, rather than the client, to keep track of all the instances. In some sense, if the purpose of what you're doing is to make it easier for clients to have access to a global list of all the objects that exist, you may want to consider just putting a different list somewhere else that's globally accessible so that the objects themselves aren't the ones responsible for keeping track of themselves.
I would recommend using one of a number of alternate approaches:
Just have the client do this. If the client needs to keep track of all the instances, just have them always create the array they need and populate it. That way, if multiple clients need different arrays, they can do so. You also avoid the memory leak issues if you do this properly.
Have each object take, as part of its constructor, a context in which to be constructed. For example, if all of these objects are nodes in a quadtree, have them take a pointer to the quadtree in which they'll live as a constructor parameter, then have the quadtree object store the list of the nodes in it. After all, it seems like it's really the quadtree's responsibility to keep track of everything.
Keep doing what you're doing, but using something with weak references. For example, you might consider using some variation on a WeakHashMap so that you do store everything, but if the objects are no longer needed, you at least don't have a memory leak.
I would like my class to have a stored property that can be assigned immutable arrays. If I do this:
class MyClass{
var myItems:[String]
}
I can assign different arrays to my property, but the arrays will be mutable. If I do this:
class MyClass{
let myItems:[String]
}
My array is immutable, but I can't ever change what's assigned to it. Is there any way to have my cake not mutate it too?
The best I've come up with is creating a wrapper around the array, then using that type for the property, like so:
class MyClass{
struct ImmutableWrapper{
let array:[String]
}
var myItems:ImmutableWrapper
}
…which is not exactly elegant.
I'd propose a slightly more concise solution than #matt's excellent answer, which again takes advantage of access modifiers. Instead of specifying a separate private variable, and exposing a public/internal computed variable that only provides a getter, you can let Swift do this for you by using private(set):
class MyClass {
private(set) var myItems = [String]()
}
This specifies that the setter should be private to the current file scope. The getter retains the default access level (public/internal) so outside classes can still retrieve a copy of myItems (a copy since arrays are structs, so are passed by value*).
But you might then think you can just call a mutating method like append() on myItems, and in doing so modify it from outside the class (after all, we're getting var myItems, not let myItems). But Swift is smart enough to recognise that the array should be immutable from outside MyClass:
let object = MyClass()
object.myItems.append("change me")
// ^ ~~~~~~
// Immutable value of type '[(String)]' only has mutating members named 'append'
So this achieves a very similar effect to the old Objective-C paradigm of maintaining a private NSMutableArray, and exposing a public readonly NSArray that creates an immutable copy of the private array when called. Much more elegant though, don't you think?
*In actual fact Swift is really smart with passing by value, and may not even make a copy of the array until the point it is modified, and even then may only keep track of the changes (internally). This means you can assign an array with many thousands of items without incurring a massive performance penalty.
The question is oddly posed, since your first myItems is not an array of various arrays, it's just an array of Strings. However, I'll try to discuss the matter in a more general way.
Swift does not distinguish mutable from immutable arrays in the way Cocoa NSArray does. But why do you need this? Cocoa needs it because an NSArray is a class, so if it were mutable, it could be changed behind MyClass's back. But in Swift, Array is a value type, so that can't happen.
So what's the problem you are really trying to solve? You should ask yourself what contract you are trying to get outside objects to fulfill, and try to write that contract into the structure of MyClass. Your array of structs is a perfectly reasonable approach. I think, though, that what you're after here might actually be privacy, not immutability. For example, I might say this:
class MyClass{
private var myItemsHidden = [String]()
var myItems:[String] {
get {
return myItemsHidden
}
set {
myItemsHidden = newValue
}
}
}
Now, assuming MyClass is alone in its own file (because private in Swift means private to a file), myItemsHidden can be manipulated in any way you like from inside MyClass, so presumably MyClass knows not to mutate any subarrays or whatever it is you are trying to prevent. It is up to MyClass what it allows itself to do with myItemsHidden.
But from outside MyClass, myItemsHidden does not exist; there is only myItems, and the only thing anyone can do to it is get it and set it. (If they get it and change it, the original is unaffected. They cannot mutate the original.) If your purpose is to prevent anyone from outside setting myItems at all, delete the setter function:
class MyClass{
private var myItemsHidden = [String]()
var myItems:[String] {
get {
return myItemsHidden
}
}
}
Now myItems is merely a dispensed (vended) array and no more.
If the idea is that other classes should be allowed to add new arrays to an array of arrays, you could add a MyClass method that lets them do that. In other words, now that this thing is private, it is up to you what kind of access you give others to it. MyClass becomes the gatekeeper for what other classes can do with this value, because the value itself is hidden behind the private wall.
You can probably try NSArray. The array itself is immutable and the variable can be assigned again.
class MyClass{
var myItems:NSArray
}
Why would I want a method that needs an instance? Why wouldn't I make all my methods static?
Why would you not want any state anywhere in your program?
Can you imagine if there were no String instances, and everything on String was static? How would you represent two distinct sequences of characters? Now apply the same logic to other code.
Fundamentally, OO languages are built around the idea of objects with state: one instance of Book isn't the same an another instance of Book - each Book instance encapsulates its name, author, publication date etc. How would you model that with only static methods, and no instances?
Of course you could make all your methods static and pass in a Book as the first parameter on each call that needed to use the state. Behind the scenes, something pretty much like that is already happening... except you've then lost polymorphism, so interfaces, abstract classes etc are useless. Not good.
Because objects are state and behavior together, encapsulated into a single component.
If you have individual instances, it means they can each have private data that varies from instance to instance.
Static data and methods are shared at the class level. Individual instances cannot have different static data.
Static methods can't directly access the member variables within an object - they can only access static variables.
If you had a car class and a static data member like an integer in it, you could only ever have one car because you cant make multiple instances of cars and get multiple instances of that variable - you'd only ever have the single static one.
Every car can't have the same license plate number, thus ever car needs its own license plate variable.
The methods in the class that work with that variable need to be non-static to work on it directly then.
Using the example of a "Car" class, you might have a method called "startCar()". Obviously, you want this method to interact only with a particular "instance" of a car and not be global to ALL your cars. Example in Java:
public class Car {
public void startCar() {
// code to start car
}
}
public class MyProgram {
public static void main(String[] Args) {
Car myFord = new Car();
Car myOpel = new Car();
myCar.startCar; // starts the Car "myCar" and leaves "myOpel" alone
}
}
It's also worth noting that Static Methods may not make use of Instance Variables of the class in which they are defined.
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.