I'm creating an array of different animal objects from the same super class and then using a for loop I'm retrieving a description of each animal using a method from another class but when I assign each new animal to the array it changes the name and type of each to that of the last animal. How do I get it to stop changing the parameters for each animal?
Here's my code now:
I have constructors for each type of animal listed with different descriptions for each type.
Animal[] family = new Animal[5];
family[0] = new Dog("Wrex", "dog");
family[1] = new Wolf("Fenrir", "wolf");
family[2] = new Snake("Kaa","snake");
family[3] = new Snake("Nagini", "snake");
family[4] = new Chameleon("David", "chameleon");
for(int i = 0; i < 5; i++)
{
family[i].describe();
}
This is what it prints out:
David is a chameleon.
David barks.
David moves on four legs.
David gets food from its owner.
David eats by chewing.
David is a chameleon.
David howls.
David moves on four legs.
David gets food by hunting in packs.
David eats by chewing.
Edit
My describe method is different for each animal class but they all follow this format:
public void describe()
{
System.out.println(Chameleon.getName()+ " is a " +Chameleon.getType()+ ".");
makeSound();
move();
getFood();
eatFood();
}
Edit 2
Here is a rough outline of each class and subclass
public class Animal {
private static String name;
private static String type;
public Animal(String name, String type)
{
Animal.name = name;
Animal.type = type;
}
public static String getName() {
return name;
}
public void setName(String name) {
Animal.name = name;
}
public static String getType() {
return type;
}
public void setType(String type) {
Animal.type = type;
}
public class Mammal extends Animal {
public Mammal(String name, String type)
{
super(name, type);
}
}
reptile is the same as mammal
each of the last subclass looks like this with the describe method posted above
public class Chameleon extends Reptile{
public Chameleon(String name, String type)
{
super(name, type);
}
static !!!
remove the static keyword. That's the only problem. Read more about it here
use this and change things accordingly
private String name;
private String type;
Variables name and type are declared as static in class "Animal". Therefore they are shared by all instances of the "Animal" class.
Related
I've got a WCF service that passes around status updates via a struct like so:
[DataContract]
public struct StatusInfo
{
[DataMember] public int Total;
[DataMember] public string Authority;
}
...
public StatusInfo GetStatus() { ... }
I expose a property in a ViewModel like this:
public class ServiceViewModel : ViewModel
{
public StatusInfo CurrentStatus
{
get{ return _currentStatus; }
set
{
_currentStatus = value;
OnPropertyChanged( () => CurrentStatus );
}
}
}
And XAML like so:
<TextBox Text="{Binding CurrentStatus.Total}" />
When I run the app I see errors in the output window indicating that the Total property cannot be found. I checked and double checked and I typed it correctly. The it occurred to me that the errors specifically indicate that the 'property' cannot be found. So adding a property to the struct made it work just fine. But this seems odd to me that WPF can't handle one-way binding to fields. Syntactically you access them the same in code and it seem silly to have to create a custom view model just for the StatusInfo struct. Have I missed something about WPF binding? Can you bind to a field or is property binding the only way?
Binding generally doesn't work to fields. Most binding is based, in part, on the ComponentModel PropertyDescriptor model, which (by default) works on properties. This enables notifications, validation, etc (none of which works with fields).
For more reasons than I can go into, public fields are a bad idea. They should be properties, fact. Likewise, mutable structs are a very bad idea. Not least, it protects against unexpected data loss (commonly associated with mutable structs). This should be a class:
[DataContract]
public class StatusInfo
{
[DataMember] public int Total {get;set;}
[DataMember] public string Authority {get;set;}
}
It will now behave as you think it should. If you want it to be an immutable struct, that would be OK (but data-binding would be one-way only, of course):
[DataContract]
public struct StatusInfo
{
[DataMember] public int Total {get;private set;}
[DataMember] public string Authority {get;private set;}
public StatusInfo(int total, string authority) : this() {
Total = total;
Authority = authority;
}
}
However, I would first question why this is a struct in the first place. It is very rare to write a struct in .NET languages. Keep in mind that the WCF "mex" proxy layer will create it as a class at the consumer anyway (unless you use assembly sharing).
In answer to the "why use structs" reply ("unknown (google)"):
If that is a reply to my question, it is wrong in many ways. First, value types as variables are commonly allocated (first) on the stack. If they are pushed onto the heap (for example in an array/list) there isn't much difference in overhead from a class - a small bit of object header plus a reference. Structs should always be small. Something with multiple fields will be over-sized, and will either murder your stack or just cause slowness due to the blitting. Additionally, structs should be immutable - unlesss you really know what you are doing.
Pretty much anything that represents an object should be immuatable.
If you are hitting a database, the speed of struct vs class is a non-issue compared to going out-of-process and probably over the network. Even if it is a bit slower, that means nothing compared to the point of getting it right - i.e. treating objects as objects.
As some metrics over 1M objects:
struct/field: 50ms
class/property: 229ms
based on the following (the speed difference is in object allocation, not field vs property). So about 5x slower, but still very, very quick. Since this is not going to be your bottleneck, don't prematurely optimise this!
using System;
using System.Collections.Generic;
using System.Diagnostics;
struct MyStruct
{
public int Id;
public string Name;
public DateTime DateOfBirth;
public string Comment;
}
class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public string Comment { get; set; }
}
static class Program
{
static void Main()
{
DateTime dob = DateTime.Today;
const int SIZE = 1000000;
Stopwatch watch = Stopwatch.StartNew();
List<MyStruct> s = new List<MyStruct>(SIZE);
for (int i = 0; i < SIZE; i++)
{
s.Add(new MyStruct { Comment = "abc", DateOfBirth = dob,
Id = 123, Name = "def" });
}
watch.Stop();
Console.WriteLine("struct/field: "
+ watch.ElapsedMilliseconds + "ms");
watch = Stopwatch.StartNew();
List<MyClass> c = new List<MyClass>(SIZE);
for (int i = 0; i < SIZE; i++)
{
c.Add(new MyClass { Comment = "abc", DateOfBirth = dob,
Id = 123, Name = "def" });
}
watch.Stop();
Console.WriteLine("class/property: "
+ watch.ElapsedMilliseconds + "ms");
Console.ReadLine();
}
}
I can only guess why they only support properties: perhaps because it seems to be a universal convention in the .NET framework never to expose mutable fields (probably to safeguard binary compatibility), and they somehow expected all programmers to follow the same convention.
Also, although fields and properties are accessed with the same syntax, data binding uses reflection, and (so I've heard) reflection must be used differently to access fields than to access properties.
I have converted a list of JSON objects to a generic list.
The Data structure on the items is as following
public class Person
{
private string Name;
private int Age;
private string Weightloss;
}
The Weightloss string is of type "109-102" and I need to calculate how much each person has lost in weight since they signed up. I my examlpe it'd be 7. How to I, using LINQ Method syntax, calculate each weight loss (or gain). I assume I'll need to split up the string but I'm not really sure how
Rather odd question, but if Linq is what you want, here is how one can go about it:
Create a function inside your class to calculate the weight difference:
public class Person
{
//Constructor
public Person(string name, int age, string weightLoss)
{
Name = name;
Age = age;
Weightloss = weightLoss;
}
public string Name;
private int Age;
private string Weightloss;
/// <summary>
/// Calculates the weight difference from the WeightLoss property.
/// </summary>
/// <returns></returns>
public int GetWeightLoss()
{
//Get the values
var parts = Weightloss.Split('-')
.Select(value => Convert.ToInt32(value))
.ToArray();
//Calculate the difference
var difference = parts[0] - parts[1];
return difference;
}
}
Not clean and I personally dislike it but it's homework so...
I added a constructor for initialization and changed the Name field to public so you can output it:
var list = new List<Person>()
{
new Person("Juan", 30, "109-102"),
new Person("Max", 35, "119-103"),
new Person("John", 40, "109-105"),
};
//Figure out the largest loss
var maxLossPerson = list.OrderByDescending(p => p.GetWeightLoss()).First();
Console.WriteLine($"{maxLossPerson.Name} lost the most with {maxLossPerson.GetWeightLoss()} pound(s)");
Output:
Max lost the most with 16 pound(s)
You're either going to use a string split or a regular expression.
Assuming your string is always formatted "Weight1-Weight2", a string split would be fairly simple:
public int[] ParseWeights(string weightString) {
var weights = weightString.Split('-');
var beginningWeight = Convert.ToInt32(weights[0]);
var endingWeight = Convert.ToInt32(weights[1]);
return new int[] {beginningWeight, endingWeight};
}
Add another property to Person:
public class Person
{
private string Name;
private int Age;
private string Weightloss;
public int WeightLost
{
get
{
int[] values = Weightloss.Split('-').Select(i => int.Parse(i)).ToArray();
return values[0] - values[1];
}
}
}
If you look for a even more Linq way, you can use the follow way:
private string Weightloss;
public int WeightLossInt => Weightloss
.Split('-')
.Select((value, index) => index == 0 ? int.Parse(value) : -int.Parse(value))
.Sum();
}
I have 3 kinds of GameObject, namely blueBook, redBook and greenBook. There are 2 blueBook, 7 redBook and 4 greenBook in the scene.
They are each assigned with the following example script that have 3 properties.
public class blueBook : MonoBehaviour {
public string type = "BlueBook";
public string colour = "Blue";
public float weight;
float s;
void Start () {
float weightValue;
weightValue = Random.value;
weight = Mathf.RoundToInt (700*weightValue+300);
s=weight/1000; //s is scale ratio
transform.localScale += new Vector3(s,s,s);
}
// Update is called once per frame
void Update () {
}
}
In the new class, I want to take all the variables of the GameObject (type, colour, weight) and store them inside an array. How to do this?
After they are all stored inside the array, user will input an weight. Then another class will search through all the info to delete both the array and GameObject(in the scene) with the same amount of weight.
Thank you.
UPDATE
blueBook.cs
public class blueBook: MonoBehaviour {
public string type = "blueBook";
public string colour = "Red";
public float weight;
float s;
void Start () {
float weightValue;
weightValue = Random.value;
weight = Mathf.RoundToInt (500*weightValue+100);
s=weight/1000; //s is scale ratio
transform.localScale += new Vector3(s,s,s);
Debug.Log(weight);
}
// Update is called once per frame
void Update () {
}
}
block.cs
public class block: MonoBehaviour{
public List<GameObject> players;
void Start()
{ Debug.Log(players[1].GetComponent<blueBoook>().weight);
}
// Update is called once per frame
void Update () {
}
The debug.log for block.cs displayed 0 everytime eventho it display otherwise in debug.log of bluebook.cs. It is because it displayed the initial number? I don know wat is wrong
For all blocks in one list you can create a script that has a public list and you drag all your gameobjects into the list in the inspector.
using System.Collections.Generic;
public class ObjectHolder : MonoBehaviour
{
public List<GameObject> theBooks;
// You can remove by weight e.g. like this
public void DeleteByWeight(float inputWeight)
{
for(int i = theBooks.Count - 1; i >= 0; i--)
{
if(theBooks[i].GetComponent<Book>().weight == inputWeight)
Destroy(theBooks[i]);
theBooks.RemoveAt(i);
}
}
}
}
The script on the blocks needs to be renamed to the same name for all (Book in my example). From your code that is no problem since they only differ in the value of the members.
I am using resteasy, and till now I am just sending and receiving string as parameters and every thing was OK, but now I want to send a complex object ( List<Map<String, ObjectVal>> ) as one of my parameters. My objectVal class has two simple field ( id and value, with getters and setters).
I can find different question and answers for sending objects as parameters but all of them are missing something and not useful for me.
here is my functions with a simple string parameter
#GET
#Path("/isUserAuthorizedToDocument")
public Response isUserAuthorizedToDocumentService(
#QueryParam("userID") String userID){
.............
.............
}
and the client
private ClientRequest req =new ClientRequest(....url with path and ....)
req.queryParameter("userID", user.getUserId());
ClientResponse<Boolean> response = req.get(Boolean.class);
Now I want to send a parameter from my client in the form of List<Map<String,ObjectVal>> and recieve it in my rest function.
My ObjectVal class
#XmlRootElement(name = "objectValueDTO")
public class ObjectValueDTO implements Serializable {
/**
* Id for this class
*/
private static final long serialVersionUID = 164186789404269392L;
// Id on object type
private String objectTypeID = "";
// Selection
private String value = "";
/** Getter and Setters */
#XmlElement
public String getObjectTypeID() {
return objectTypeID;
}
public void setObjectTypeID(String objectTypeID) {
this.objectTypeID = objectTypeID;
}
#XmlElement
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
any help will be appreciated
I may be niave on this. But when you have to send complex parameters, you need to use PUT and send the parameters in the request.
I have the following Global class file:
Global.cs
public static class Global
{
private static string _globalVar = "";
public static string GlobalVar
{
get { return _globalVar; }
set { _globalVar = value; }
}
}
I set the new value of string GlobarVar in Form1.cs as '1234'.
Form1.cs
public Form1()
{
InitializeComponent();
Global.GlobalVar = "1234";
}
I tried to display the value to Form2.cs using the message box
public Form2()
{
InitializeComponent();
MessageBox.Show(Global.GlobalVar); // displays blank values
}
Am I missing something?
Four options:
You're not constructing Form1 before you construct Form2
Something else is setting Global.GlobalVar back to null or an empty string
Your forms are in different app domains, so they'll have entirely separate Global types
You're running the application twice; static variables don't live on across different processes
It's hard to tell which of these is the case, but personally I'd try to avoid using global state to start with. It's a pain for testability and reasoning about how your program works.
Try your property page (file Global.cs) like these:
public class Global
{
private static string _globalVar;
public string GlobalVar
{
get { return _globalVar; }
set { _globalVar = value; }
}
}