Chengyu Sun California State University, Los Angeles CS4540 Special Topics in Web Development C# for Java Programmers: OO Programming Chengyu Sun California State University, Los Angeles
A Java Class package shapes; public class Circle { private static int idSeed = 1; private int id; private double radius; public Circle(double radius) { id = idSeed++; this.radius = radius; } public int getId() { return id; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } } Circle c1 = new Circle(2.5); System.out.println( c1.getId() );
Terminology Package Class, object, instance Access modifier Field, method, constructor, member Static, this
Properties in Java Properties are NOT fields Properties in Java are defined by getters/setters Accessed as regular method (i.e. getter/setter) calls in Java Accessed like fields in derived languages like Expression Language, e.g. ${c1.id} public int getId() read-only property id public double getRadius() Public void setRadius(double) read-write property radius
Why Properties? We want something look/behave like fields, but also have control over how they are accessed Read-only, write-only, read-write Additional logic in getter/setter
What About C# All the terminology are same in C# except that Package is replaced by namespace C# has direct syntax for properties
Circle Class in C# namespace Shapes { public class Circle { private static int idSeed = 1; public int Id { get; } public double Radius { get; set; } public Circle(double radius) { Id = idSeed++; Radius = radius; } } Circle c1 = new Circle(2.5); Console.WriteLine( c1.Id );
Comparison to Java Class Similarities Different naming conventions Property syntax
More on C# Classes Access modifiers Method Constructor and initializer Properties static const vs. readonly
Access Modifiers public, private protected: can be accessed from within class and subclasses internal: can be accessed from the same assembly (a .dll or .exe file, like a .jar file in Java) No access modifier (a.k.a. default modifier) internal for types private for members
A Regular Method public int Add( int x, int y ) { return x + y; }
Expression-Bodied Member public int Add( int x, int y ) => x + y; Single-lined methods can be simplified into one expression or statement Applies to constructors and property getters/setters as well More on lambda operator later
Optional Arguments Some parameters may have default values public int Add( int x, int y = 10 ) { return x + y; } int sum = Add(20); Some parameters may have default values Such parameters must be placed at the end of the parameter list. Why??
Named Arguments public int Add( int x=1, int y=2, int z=3) { return x + y + z; } int sum1 = Add(10,20); int sum2 = Add( y : 20, z : 30 ); Int sum3 = Add( z : 30, x : 10 ); Specify both parameter name and value when calling a method
Parameter Modifier ref Makes a value typed parameter pass-by-reference The ref keyword must be used on both the parameter and the argument Example: Switch(x,y)
Parameter Modifier out Similar to ref with the additional requirement that the method must assign an out parameter a value Useful when a method needs to return more than one value Example: int.TryParse()
Parameter Modifier params Allows passing multiple arguments to a single array parameter Only one params parameter is allowed, and it must be the last one in the parameter list Example: Add(values)
About Constructors Default constructor means a parameter-less constructor No constructor compiler automatically generates an empty default constructor A constructor calling another constructor. For example: public Circle( double radius ) : this() { Radius = radius; }
Object Instantiation and Initialization public class Person { public string Name { get; set; } public int Age { get; set; } public Person() {} public Person( string name ) { Name = name; } } Person p = new Person(); p.Name = "John"; p.Age = 20; Person p = new Person("John"); p.Age = 20;
Object Initializer Person p = new Person() { Name = "John", Age = 20 }; Person p = new Person { Name = "John", Age = 20 }; Person p = new Person("John") { Age = 20 }; Compare the syntax with array initialization and named arguments
Full Property Syntax public Radius { get { return Radius; } set { Radius = value; } } The simplified syntax {get; set;} is called auto-implemented properties
Read-Only and Write-Only Properties No setter read-only properties No getter write-only properties Auto-implemented properties must have getters
About static Like in Java, a static member is associated with the class rather than an object (i.e. an instance) of the class A static constructor can be used to initialize static fields A static class contains only static members
const vs readonly A const field is both constant and static, and the initial value must be provided when the field is defined A readonly field is constant but not static, and the initial value can be assigned in a constructor
An Inheritance Example Object Account CDAccount
Account class Account { public int Id { get; set; } public double Balance { get; set; } public Account(int id, double balance) { Id = id; Balance = balance; } public virtual double Deposit( double amount) { if(amount > 0) Balance += amount; return Balance;} public override string ToString() { return $"Account #{Id}: ${Balance}";} }
CDAccount class CDAccount : Account { public int Term { get; set; } public CDAccount(int id, double balance, int term): base(id, balance) { Term = term; } public override double Deposit( double amount) { Console.WriteLine("Cannot deposit into a CD Account"); return Balance; } public override string ToString() { return $"CDAccount #{Id}: ${Balance}, {Term} Days"; } }
Syntactical Difference Comparing to Java Inherit from a base class (i.e. superclass) Call the base class constructor Call a base class method
Override A subclass re-implement (i.e. change) a method defined in the base class Important for polymorphism Account[] accounts = new Account[2]; accounts[0] = new Account(1, 100); accounts[1] = new CDAccount(2, 100, 90); Console.WriteLine(accounts[0]); Console.WriteLine(accounts[1]);
Overriding in C# Must use virtual to indicate that a method can be overridden Must use override to indicate that a method is overriding a base class method
Shadowing Without override, the subclass method hides the base class method, known as shadowing Shadowing can be made explicit by using the new keyword Shadowing affects polymorphism Example: Deposit() in Account and CDAccount
Overloading A class may have multiple methods having the same name but different signatures Like in C++, C# supports operator overloading Example: overload + for account deposit public static Account operator + (Account a, double amount) Must be public and static Result Operator to overload Operand 1 Operand 2
More About The Operator Overloading Example Discards (i.e. _) are temporary, dummy variables that are intentionally unused Overriding + (or -) applies automatically to += (or -=)
Partial Class The definition of a class can be split into multiple source files public partial class Employee { public void DoWork() {} } public void GoToLunch() {} Particularly useful with auto-generated source
An Abstract Class Example abstract class Shape { public double CenterX { get; set; } public double CenterY { get; set; } public void Move( double x, double y) { CenterX = x; CenterY = y;} public abstract void Draw(); }
About Abstract Class An abstract class contains one or more abstract methods An abstract method defines the method signature but no implementation Abstract methods must be implemented in a subclass (unless the subclass is also abstract) An abstract class can be used as a type but cannot be instantiated. So when is an abstract class useful??
Interface An interface is like an abstract class with only abstract members (i.e. methods and properties) Perfect for describing API Usually starts with I in C# naming conventions, e.g. inteface IDrawable { void Draw(); } Interface members don't have access modifiers – they are always public.
About Interface and Class Like in Java (and unlike in C++), a C# class can only inherit from one base class Like in Java, a class can implements multiple interfaces, e.g. class Rectangle : Shape, IDrawable, IColorable { … }
Create An Object Without Creating An Class … In JavaScript, we can create an object without a class: var car = { make: "Honda", model: "Civic" }; var make = "Honda"; var model = "Civic"; var car = { make: make, model: model }; var car = { make, model };
… Create An Object Without Creating A Class We can do something similar in C#: Object initializer syntax without the class name (i.e. "anonymous") string Model = "Honda"; string Make = "Civic"; var car = new { Model, Make }; var car = new { Model = "Honda", Make = "Civic" };
Anonymous Type The compiler automatically creates a class with read-only properties var is necessary because we don't know (or care) the name of the auto-generated class Very handy when we want to create an one-use object
Tuple Combine multiple values into one var tuple1 = ("Honda", "Civic"); (string, string) tuple2 = ("Honda", "Civic"); Console.WriteLine(tuple1.Item1 + " " + tuple2.Item2); var tuple3 = (Make: "Honda", Model: "Civic"); (string Make, string Model) tuple4 = ("Honda", "Civic"); Console.WriteLine(tuple3.Make + " " + tuple4.Model); string Make = "Honda"; string Model = "Civic"; var tuple5 = (Make, Model); Console.WriteLine(tuple5.Make + " " + tuple5.Model);
Tuple vs. Anonymous Type Anonymous type is a reference type while tuple is a value type Tuple type (e.g. (string,string)) is explicit so it can be used as method parameters and return values
Readings Pro C# 7: Chapter 4, 5, 6