I have two classes, i want to put instances of a class Bear in a list from class Cave like below, but that code doesn't works. Should classes be in relationship? How can I change code?
class Bear
{
public Bear(int age, string name)
{
this.Age = age;
this.Name = name;
}
}
class Cave
{
List<Bear> cave = new List<Bear>();
cave.Add(new Bear(16, "Johnny"));
cave.Add(new Bear(10,"Herman"));
}
If you are getting any errors, please post them. You can't put code like that directly in the class. All executable code must be inside a method. Move the code in your Cave class into a method:
class Bear
{
public int Age { get; set; }
public string Name { get; set; }
public Bear(int age, string name)
{
this.Age = age;
this.Name = name;
}
}
class Cave
{
List<Bear> cave = new List<Bear>();
public Cave()
{
cave.Add(new Bear(16, "Johnny"));
cave.Add(new Bear(10,"Herman"));
}
}
Related
Firstly I'd like to say that I truly sorry if this is an idiotic question but I just started learning about Classes and I've thought that I managed to understand it but this confused the heck outta me so seems like I didn't
I'm doing this C# OOP edx course where I had to make 5 classes (student, teacher, UProgram, degree, course) in different class files and there's this task:
Instantiate a UProgram object called Information Technology.
Instantiate a Degree object, such as Bachelor, insude the UProgram object.
Instantiate a Course object called softeng inside the Degree object.
Was done, (hopefully) no issues with that one
and 3. - eh.
How I was thinking (bear in mind, im a beginner so):
First I've thought of nested classes but I wasn't really sure about how they work and didn't think I could put the classes in different files as they should be nested (?)
And then I tried something with the constructor but I couldn't see how I could make it work
So now my final try was to create methods inside the classes (except for the Teacher and Student one as they won't have anything ""belonging to them"" like a Course has students and teachers belonging to it
So I have the method in the form of (- let's say we're in the Degree class, having a method for creating several Courses for this degree -):
public void Newcourse(string Cname, Course sth)
{
sth = new Course();
sth = Cname;
}
And before I can use it, I have to write the
Course softeng = new Course();
line aka make an instance of the Course class before I can do the 3. point of the task
The whole code:
UProgram.cs
public class UProgram
{
public void Newdegree(string Dname, Degree sth)
{
sth = new Degree();
sth.Dname = Dname;
}
}
Degree.cs
public class Degree : UProgram
{
public string Dname { get; set; }
public void Newcourse(string Cname, Course sth)
{
sth = new Course();
sth.Cname = Cname;
}
}
Course.cs
public class Course : Degree
{
public void NewTeacher(string FirstName, string LastName, Teacher sth)
{
sth = new Teacher();
sth.FirstName = FirstName;
sth.LastName = LastName;
}
public void NewStudent(string FirstName, string LastName, Student sth)
{
sth = new Student();
sth.FirstName = FirstName;
sth.LastName = LastName;
}
public string Cname { get; set; }
}
Teacher.cs
public class Teacher : Course
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Student.cs
public class Student : Course
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Program.cs
class Program
{
static void Main(string[] args)
{
var Information_Technology = new UProgram();
Degree bachelors = new Degree();
Information_Technology.Newdegree("Bachelors", bachelors);
Course softeng = new Course();
bachelors.Newcourse("Software Engineering", softeng);
Teacher t1 = new Teacher();
softeng.NewTeacher("Colin", "Firth", t1);
Student s1 = new Student();
softeng.NewStudent("Mary", "Sue", s1);
Student s2 = new Student();
softeng.NewStudent("Joseph", "Jojo", s2);
Console.ReadLine();
}
}
I know-I know, it's very convoluted and I'm not even sure whether this is good or not but that was all I could come up with and I'd be very grateful if any of you could help me out (in a tone that won't make me cry)
Thank you and again, sorry for this mess of a code, eh, i tried
The wording does seem a bit strange, but I believe they are simply saying that this class should contain a property of the type it is meant to "contain", and instantiate it in the constructor. For example:
public class Degree
{
public Course Course { get; set; }
public Degree()
{
Course = new Course();
}
}
public class Course
{
public Student Student { get; set; }
public Course()
{
Student = new Student();
}
}
public class Student
{
public Student()
{
}
}
Upon creating a an instance of Degree, it will create an instance of a Course inside it, which will create an instance of a Student inside it. Thus Degree contains a Course which contains a Student.
The example above is using the constructors to instantiate these but as they are public properties they could also just be created from outside it (in which case the constructors above are unnecessary):
var degree = new Degree();
degree.Course = new Course();
degree.Course.Student = new Student();
Just a few comments:
I have big doubts that you need any inheritance here. For example: Student : Course - I doubt that "Student is a Course" :) . So, you probably need some composition here. I don't know (and can't remember) what diamonds in your picture exactly means, but can guess that filled diamond - is one item (or at least one, not sure) and empty means many items.
So, here how I would do this (you can split each class to separate file):
public class UProgram
{
public string Name { get; set; }
public Degree Degree { get; set; }
public UProgram(string name, Degree degree)
{
Name = name;
Degree = degree;
}
}
public class Degree
{
public string Name { get; set; }
public Course Course { get; set; }
public Degree(string name, Course course)
{
Name = name;
Course = course;
}
}
public class Course
{
public List<Teacher> Teachers { get; set; }
public List<Student> Students { get; set; }
public string Name { get; set; }
public Course(string name, List<Teacher> teachers, List<Student> students)
{
Name = name;
Teachers = teachers;
Students = students;
}
}
public class Teacher
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
and Main function:
static void Main(string[] args)
{
var teachers = new List<Teacher>
{
new Teacher
{
FirstName = "Colin",
LastName = "Firth"
}
};
var students = new List<Student>
{
new Student
{
FirstName = "Mary",
LastName = "Sue"
},
new Student
{
FirstName = "Joseph",
LastName = "Jojo"
}
};
var softEngCourse = new Course("Software Engineering", teachers, students);
var bachelorDegree = new Degree("Bachelor", softEngCourse);
var technologyProgram = new UProgram("Technology", bachelorDegree);
Console.ReadLine();
}
I still not sure that this exactly what your course is expected from you, this is how I would write code like this (with some minor changes, but it doesn't matter here).
Why in that way? Because it is almost always better to build an object in a "working" state when it explicitly receives everything that it needs, rather than create a raw object that will start in "invalid" state. Secondly, it is usually better to not "bake in" parameters values inside, but give a class consumer (I mean "developer" here) to configure it.
You are misunderstanding the task. Course should not inherit from Degree, since Course is not a Degree. Instead, you will need to define Course data member in your Degree class. Neither Student, nor Teacher is a Course, therefore you should not inherit them from Course. They are members.
I assume that a Degree can be achieved by a single Course.
I assume that a Course has a single Teacher.
I assume that a Course can have multiple Students.
This means that you have a Person class, like this, since both Student and Teacher is a Person:
public class Person {
protected String firstName;
protected String lastName;
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
Now, inherit Teacher from Person:
public class Teacher : Person {
public Teacher(String firstName, String lastName) : base(firstName, lastName) {
}
}
and Student:
public class Student : Person {
public Student(String firstName, String lastName) : base(firstName, lastName) {
}
}
Now, let's define Course:
public class Course {
protected Teacher teacher;
protected List<Student> students;
protected String name;
public String getName() {
return this.name;
}
public Teacher getTeacher() {
return this.teacher;
}
public List<Student> getStudents() {
return this.students;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public void setTeacher(String firstName, String lastName) {
this.teacher = new Teacher(firstName, lastName);
}
public void addStudent(Student student) {
this.students.Add(student);
}
public void addStudent(String firstName, String lastName) {
this.students.Add(new Student(firstName, lastName));
}
public Course(String name) {
this.name = name;
this.students = new List<Student>();
}
}
Now, let's define Degree:
public class Degree {
protected String name;
protected Course course;
public String getName() {
return this.name;
}
public Course getCourse() {
return this.course;
}
public void setCourse(Course course) {
this.course = course;
}
public void setCourse(String name) {
this.course = new Course(name);
}
public Degree(String name) {
this.name = name;
}
}
Now, this is how you achieve what you wanted:
Degree degree = new Degree("mydegree");
degree.setCourse("myCourse");
Course course = degree.getCourse();
course.setTeacher("John", "Smith");
course.addStudent("James", "Doe");
Hey guys I recently started learning C# using microsoft .Net Tutorials.
I'm stuck at "Classes and Objects" Lesson.
At the end of the each lesson we have a little "homework" to do.
I need to write a program that prints out addresses for people and companies using three different classes (Person, Copmany, Address). I need to add them to collection and loop through, printing out the address for each company or person.
Here is the LINK (at the end of the page there is an example how the program should look like.
I'm not really sure how am I suppose to achieve this. Can someone please help me understand. This is what I come so far:
public class Address
{
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public override string ToString()
{
return $"{StreetAddress}, {City}, {PostalCode}, {Country}";
}
public Address()
{
StreetAddress = "Main123";
City = "SomeTown";
State = "OH";
PostalCode = "12345";
Country = "United States";
}
}
public class Person : Master
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Address ShippingAddress { get; set; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
ShippingAddress = new Address();
}
public override string ToString()
{
return $"{FirstName} {LastName} {ShippingAddress}\n";
}
}
public class Company : Master
{
public string Name { get; set; }
public Address ShippingAddress { get; set; }
public Company(string name)
{
Name = name;
ShippingAddress = new Address();
}
public override string ToString()
{
return $"{Name} {ShippingAddress}\n";
}
}
public class Master
{
public static List<Master> data = new List<Master>();
public static void Coll(Master master)
{
data.Add(master);
data.ForEach(Console.WriteLine);
}
}
class MainClass
{
public static void Main(string[] args)
{
Person John = new Person("John", "Smith");
Master.Coll(John);
}
}
If you have already reached the end of your tutorial, then it means that you have read the section about Inheritance and Polymorphism.
Please read this section again carefully.
If your task is: printing out the address for each company or person
Have a look on what the tutorial says about the ToString method:
Note that you can override the ToString method on any class where it will make sense to display string data related to an instance of the class.
So you first step would be to give the class Address the ability to display it's content, by overriding the ToString method.
You second step would be to use inheritance and create a super class which can be inherited by your 2 classes Person and Company. As it is done in the tutorial with the class Shape.
This will allow you to to add them to [a single] collection (as you wrote in your request).
Try to combine these steps and if you still have questions drop me a comment.
(Please keep rereading the tutorial, all the necessary information is in there, you just have to combine the different parts). Good fortune!
EDIT:
After you have edited your code, the next steps would be to give your classes Person and Company the ability to display information about themselves. Meaning you should override the ToString method also there.
One tip : you can use the ToString method of the class Address to display the details of the ShippingAddress. No need to write the details again ;) If you include the variable in the extrapolated string $"... the ToString method will be called implicitly and display all the details:
$"{ShippingAddress}"
One problem with your Coll method is that it is using a local variable List<Master> data as storage. This variable will cease to exist when the compiler returns from the method. Another problem is that in each call you create a new List making it impossible to store more than 1 element. What you can do is to make it a static variable inside the Master class. So that every time you add an item it will stay in memory and can be accessed later on.
You can also make the method static since it does not really require an object of type Master to be called (it does not access any class properties)
public class Master
{
public static List<Master> data = new List<Master>();
public static void Coll(Master master)
{
data.Add(master);
data.ForEach(Console.WriteLine);
}
}
You can call it like this then:
Person John = new Person("John", "Smith");
Master.Coll(John);
This is fairly straight forward. You can do it using interfaces or polymorphism.
You need put objects into collection, and iterate through all of them.
entityList = new List<IPrintable>();
foreach(var entity in entityList)
{
entity.PrintAddress();
}
To achieve this, you need to use common interface for both classes;
internal interface IPrintable
{
void PrintAddress();
}
You need to implement this interface in both classes.
public class Person : IPrintable
{
public void Print()
{
Console.WriteLine("Person's address is {0}", ShippingAddress.ToString());
}
}
public class Company : IPrintable
{
public void Print()
{
Console.WriteLine("Company's is {0}", ShippingAddress.ToString());
}
}
public class Address
{
public string ToString()
{
return string.Format(" Street: {0}, {1}, {2}, {3}, post code{4}, {5}", StreetAddress, City, State, PostalCode, Country);
}
}
Instead of having common interface you can make abstract base class, which will hold ShippingAddress field and have virtual method Print() without implementation. Then this base class will be type you use in List class
var entitylist = newList();
public abstract class ShippableEntity
{
private Address _Address;
private ShippableEntity(Address address)
{
_Address = address;
}
public abstract void Print();
public Address ShippingAddress { get { return _Address; } }
}
Then you inherit this class in Person and Company and implement Print method in concrete classes.
Then you can do:
entitylist.Add(new Person(....));
entitylist.Add(new Company(....));
and do the same thing with foreach as with interface.
You need to call base class constructor!
public class Person : ShippableEntity
{
public Person(Address address)
: base(adress)
{
}
}
I hope this helps.
I have a question about the following code.
First, these codes worked well.
However, there is no declaration only defined about “courses” in class Student.If in the Constructor of Student the argument is constant, will these code be safe?
Thanks for helping!:)
public class Student
{
public string name;
public int age;
public string[] courses;
public Student(string _name, int _age,params string[] _courses)
{
name = _name;
age = _age;
courses = _courses;//is this OK if _courses is constant?
}
}
public class work : MonoBehaviour
{
void Start()
{
/*
string[] courses={"math", "English"};
Student Tom = new Student("Tom",18,courses);
//It's wrong!
*/
Student Tom = new Student("Tom", 18, "math", "English");
string Tom_text = JsonUtility.ToJson(Tom);
Debug.Log(Tom_text);
}
}
The way you have it, anyone can change the Student object at anytime.
If you do not want anyone changing anything about the Student object once it has been created, then make it immutable like this:
public class Student
{
public string Name { get; private set; }
public int Age { get; private set; }
public IEnumerable<string> Courses { get; private set; }
public Student(string name, int age, params string[] courses)
{
this.Name = name;
this.Age = age;
this.Courses = courses;
}
}
Now people cannot change the the properties because the setters are private.
And to follow the .NET naming convention, do not use - underscores in parameter names and use Pascal Notation for property names. I have removed the underscores and used Pascal Notation for property names.
EDIT
#diemaus mentioned a good point in the comments to this answer, in C# 6:
You can actually remove the private set entirely, and just leave it { get; }. This is allowed as long as long as you only set the properties in the constructor.
what are the advantages of calling one constructor by other if there are multiple constructors?
Thanks
You don't repeat yourself.
A change in implementing one constructor also affects all the other constructors, instantly.
Copy and Pasting code is bad and should be avoided.
the same advantages you get when you do method overloading : you don't repeat the same code
public class Person
{
public Person(string name,string lastName )
{
Name = name;
LastName = lastName;
}
public Person(string name, string lastName,string address):this(name,lastName)
{
//you don't need to set again Name and Last Name
//as you can call the other constructor that does the job
Address = Address;
}
public string Name { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
Looking at the already posted answers i will just they that you always walk the way from the default constructor down to the most specialized constructor. Trying to do the same the other way around always leads to code duplications or problems:
The good way:
public class Foo()
{
public Foo()
: this(String.Empty)
{ }
public Foo(string lastName)
: this(lastName, String.Empty)
{ }
public Foo(string lastName, string firstName)
: this(lastName, firstName, 0)
{ }
public Foo(string lastName, string firstName, int age)
{
LastName = lastName;
FirstName = firstName;
Age = age;
_SomeInternalState = new InternalState();
}
}
The bad way:
public class Foo()
{
public Foo(string lastName, string firstName, int age)
: this(lastName, firstName)
{
Age = age;
}
public Foo(string lastName, string firstName)
: this(lastName)
{
FirstName = firstName;
}
public Foo(string lastName)
: this()
{
LastName = lastName;
}
public Foo()
{
_SomeInternalState = new InternalState();
}
}
The problem of the second example is that the part what to do with all the parameters is now cluttered over all constructors, instead implemented in just one (the most specialized). Just imagine you like to derive from this class. In the second example you have to override all constructors. In the first example you only have to override the most specialized constructor to get full control over every constructor.
If you want to pass default values to a base constructor.
public class YourClass
{
private int SomeInt;
public YourClass() : this(0)
{
// other possible logic
}
public YourClass(int SomeNumber)
{
SomeInt = SomeNumber;
}
}
This follows the DRY principle (Don't Repeat Yourself). A simple example, but it should illustrate the idea.
I used it when I want to pass default or null values to the other constructors. In the case above the user does not have to pass null when calling the constructor-- they can call it with nothing.
public class Widget(){
public Widget() : this(null){
}
public Widget(IRepository rep){
this.repository = rep;
}
}
There are two classes Person and Employee
when it mapped to c# code
public class Person
{
private string Name;
}
public class Employee : Person
{
private string Department;
public string GetName()
{
return "Person Name";
}
}
My question is where can i write the getters and setters for this private attributes.is it ok to write them with in the same Person and Employee classes if yes isn't there a problem with mapping? because methods are also with in the same class(GetName()) or do i have to use separate classes for writing getters and setters.i'm confused with this class diagram mapping with the code.Can any one resolve this for me??
Firstly, I would recommend you to you the properties approach and not the getters / setters one.
My take:
public class Person {
private string name;
public string Name {
get {
return this.name;
}
}
}
public class Department {
private int id;
private string name;
public int ID {
get {
return this.id;
}
}
public string Name {
get {
return this.name;
}
}
}
public class Employee : Person {
private Department department;
public Department Department {
get {
return this.department;
}
}
}
Employee.Name returns the employee name which is being declared within the Person class.