0% found this document useful (0 votes)
6 views30 pages

OOP - Create and Use Classes

The document provides an overview of object-oriented programming concepts, focusing on creating and using classes, including constructors, methods, properties, and encapsulation. It outlines the architecture of a three-layered application and presents code examples for a Product class, including object initialization and validation. Additionally, it discusses advanced topics such as static members, method overloading, and property patterns.

Uploaded by

s225146096
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views30 pages

OOP - Create and Use Classes

The document provides an overview of object-oriented programming concepts, focusing on creating and using classes, including constructors, methods, properties, and encapsulation. It outlines the architecture of a three-layered application and presents code examples for a Product class, including object initialization and validation. Additionally, it discusses advanced topics such as static members, method overloading, and property patterns.

Uploaded by

s225146096
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

4/16/2024

Object-Oriented Programming

How to create
and use classes

C12, Slide 1

Objectives
Applied
1. Given the specifications for an app that uses classes, structures,
records, or record structs, develop the app.

Knowledge
1. List and describe the three layers of a three-layered application.
2. Describe these members of a class: constructor, method, and
property.
3. Describe the concept of encapsulation.
4. Explain how instantiation works.
5. Describe the main advantage of using object initializers.
6. Explain how auto-implemented properties work and how they
differ from properties that use a private field.

C12, Slide 2

1
4/16/2024

Objectives (continued)
7. Explain how expression-bodied methods, constructors, properties,
and accessors work.
8. Explain what a static member is.
9. Describe the concept of overloading a method or constructor.
10. Explain what a required property is.
11. Describe the use of property patterns with objects.
12. Describe the difference between a class, a structure, a record and a
record struct.

C12, Slide 3

The architecture of a three-layered app


 Presentation layer (form classes)
 Middle layer (business classes)
 Database layer (database access classes)

C12, Slide 4

2
4/16/2024

The code for the Product class


namespace ProductMaintenance
{
public class Product
{
// a constructor
public Product() { }

// three public properties


public string Code { get; set; } = "";
public string Description { get; set; } = "";
public decimal Price { get; set; }

// a public method
public string GetDisplayText(string sep) =>
$"{Code}{sep}{Price.ToString("c")}
{sep}{Description}";
}
}

C12, Slide 5

Class and object concepts


 An object is a self-contained unit that has properties, methods,
and other members.
 A class contains the code that defines the members of an object.
 An object is an instance of a class, and the process of creating an
object is called instantiation.
 Encapsulation is one of the fundamental concepts of object-
oriented programming.
 The data of a class is typically encapsulated within a class using
data hiding.

C12, Slide 6

3
4/16/2024

Code that declares and creates


two Product objects
Product product1 = new Product();
product1.Code = "C#";
product1.Description = "Murach's C#";
product1.Price = 59.50m;

Product product2 = new(); // C# 9.0 and later


product2.Code = "ASPMVC";
product2.Description = "Murach's ASP.NET MVC";
product2.Price = 61.50m;

C12, Slide 7

Code that declares and creates an object


with an object initializer
Product product1 = new() { // C# 9.0 and later
Code = "C#",
Description = "Murach's C#",
Price = 59.50m
};

C12, Slide 8

4
4/16/2024

The dialog for adding a class

C12, Slide 9

The starting code for a new class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProductMaintenance
{
internal class Product
{
}
}

C12, Slide 10

10

5
4/16/2024

Getting and setting the value of a property


A statement that sets the value of a property
product.Code = txtProductCode.Text;

A statement that gets the value of a property


string code = product.Code;

C12, Slide 11

11

A read-only property with a getter


and an initial value
public string Code { get; } = "C#";

The same read-only property coded


with an expression body
public string Code => "C#";

C12, Slide 12

12

6
4/16/2024

A property with an init-only setter


(C# 9.0 and later)
public string Code { get; init; };

A statement that uses an object-initializer


to set the init-only property
Product product2 = new() { Code = "C#" };

C12, Slide 13

13

A method that accepts parameters


public string GetDisplayText(string sep)
{
return $"{Code}{sep}{Price.ToString("c")}{sep}
{Description}";
}

The same method coded with an expression body


public string GetDisplayText(string sep) =>
$"{Code}{sep}{Price.ToString("c")}{sep}{Description}";

C12, Slide 14

14

7
4/16/2024

Constructors with and without parameters


A constructor with no parameters
public Product()
{
}

A constructor with three parameters


public Product(string code, string description,
decimal price)
{
this.Code = code;
this.Description = description;
this.Price = price;
}

C12, Slide 15

15

Statements that call these constructors


Product product1 = new Product();
Product product2 = new(); // C# 9.0 and later
Product product3 = new Product("C#","Murach's C#",59.50m);
Product product4 = new("C#", "Murach's C#", 59.50m);
// C# 9.0 and later

C12, Slide 16

16

8
4/16/2024

A constructor with an expression body


(C# 7.0 and later)
public Product(string code) => this.Code = code;

A constructor with an expression body


and a tuple (C# 7.0 and later)
public Product(string code, string description,
decimal price) =>
(this.Code, this.Description, this.Price) =
(code, description, price);

C12, Slide 17

17

A class that contains static members


public static class Validator
{
public static string LineEnd { get; set; } = "\n";

public static string IsPresent(


string value, string name)
{
string msg = "";
if (value == "")
{
msg = $"{name} is a required field.{LineEnd}";
}
return msg;
}
}

C12, Slide 18

18

9
4/16/2024

Code that uses static members


string errorMessage = "";
errorMessage += Validator.IsPresent(
txtCode.Text, nameof(Product.Code));
errorMessage += Validator.IsPresent(
txtDescription.Text, nameof(Product.Description));
if (errorMessage != "")
{
MessageBox.Show(errorMessage, "Entry Error");
}

C12, Slide 19

19

A using directive for the static Validator class


using static ProductMaintenance.Validator;

C12, Slide 20

20

10
4/16/2024

The Product Maintenance form

C12, Slide 21

21

The New Product form

C12, Slide 22

22

11
4/16/2024

The Confirm Delete dialog

C12, Slide 23

23

The code for the Product Maintenance form


(part 1)
public partial class frmProductMain : Form
{
public frmProductMain()
{
InitializeComponent();
}
private List<Product> products = null!;

private void frmProductMain_Load(object sender, EventArgs e)


{
products = ProductDB.GetProducts();
FillProductListBox();
}
private void FillProductListBox()
{
lstProducts.Items.Clear();
foreach (Product p in products) {
lstProducts.Items.Add(p.GetDisplayText("\t"));
}
}

C12, Slide 24

24

12
4/16/2024

The Product Maintenance code (part 2)


private void btnAdd_Click(object sender, EventArgs e)
{
frmNewProduct newProductForm = new();
Product product = newProductForm.GetNewProduct();
if (product != null)
{
products.Add(product);
ProductDB.SaveProducts(products);
FillProductListBox();
}
}

private void btnDelete_Click(object sender, EventArgs e)


{
int i = lstProducts.SelectedIndex;
if (i != -1)
{
Product product = products[i];
string message = "Are you sure you want to delete "
+ product.Description + "?";

C12, Slide 25

25

The Product Maintenance code (part 3)


DialogResult button =
MessageBox.Show(message, "Confirm Delete",
MessageBoxButtons.YesNo);
if (button == DialogResult.Yes)
{
products.Remove(product);
ProductDB.SaveProducts(products);
FillProductListBox();
}
}
}

private void btnExit_Click(object sender, EventArgs e)


{
this.Close();
}
}

C12, Slide 26

26

13
4/16/2024

The code for the New Product form (part 1)


public partial class frmNewProduct : Form
{
public frmNewProduct()
{
InitializeComponent();
}

private Product product = null!;

public Product GetNewProduct()


{
this.ShowDialog();
return product;
}

C12, Slide 27

27

The code for the New Product form (part 2)


private void btnSave_Click(object sender, EventArgs e)
{
if (IsValidData())
{
product = new()
{
Code = txtCode.Text,
Description = txtDescription.Text,
Price = Convert.ToDecimal(txtPrice.Text)
};
this.Close();
}
}

C12, Slide 28

28

14
4/16/2024

The code for the New Product form (part 3)


private bool IsValidData()
{
bool success = true;
string errorMessage = "";
errorMessage += Validator.IsPresent(txtCode.Text,
nameof(Product.Code));
errorMessage += Validator.IsPresent(txtDescription.Text,
nameof(Product.Description));
errorMessage += Validator.IsDecimal(txtPrice.Text,
nameof(Product.Price));

if (errorMessage != "")
{
success = false;
MessageBox.Show(errorMessage, "Entry Error");
}
return success;
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
}

C12, Slide 29

29

The code for the Validator class


public static class Validator
{
public static string LineEnd { get; set; } = "\n";

public static string IsPresent(string value, string name)


{
string msg = "";
if (value == "")
{
msg = $"{name} is a required field.{LineEnd}";
}
return msg;
}
public static string IsDecimal(string value, string name)
{
string msg = "";
if (!Decimal.TryParse(value, out _))
{
msg = $"{name} must be a valid decimal value.{LineEnd}";
}
return msg;
}

C12, Slide 30

30

15
4/16/2024

The code for the Validator class (continued)


public static string IsInt32(string value, string name) {
string msg = "";
if (!Int32.TryParse(value, out _))
{
msg = $"{name} must be a valid integer value.{LineEnd}";
}
return msg;
}
public static string IsWithinRange(string value, string name,
decimal min, decimal max) {
string msg = "";
if (Decimal.TryParse(value, out decimal number))
{
if (number < min || number > max)
{
msg =
$"{name} must be between {min} and {max}.{LineEnd}";
}
}
return msg;
}
}

C12, Slide 31

31

A getter that processes the field value


before returning it
private string code;

public string Code


{
get
{
if (String.IsNullOrEmpty(code))
return "N/A";
else
return code;
}
set => code = value;
}

C12, Slide 32

32

16
4/16/2024

A setter that processes the field value


before setting it
private string code;

public string Code


{
get => code;
set
{
if (String.IsNullOrEmpty(value))
value = "N/A";
code = value;
}
}

C12, Slide 33

33

How to code overloaded methods


The GetDisplayText() method of the Product class
public string GetDisplayText(string sep) =>
$"{Code}{sep}{Price.ToString("c")}{sep}{Description}";

An overloaded version of the GetDisplayText() method


public string GetDisplayText() => GetDisplayText(", ");

Two statements that call the GetDisplayText() method


lblProduct.Text = product.GetDisplayText("\t");
lblProduct.Text = product.GetDisplayText();

C12, Slide 34

34

17
4/16/2024

How to code overloaded constructors


A constructor of the Product class with no parameters
public Product() { }

A constructor of the Product class with three parameters


public Product(string code, string description,
decimal price)
{
this.Code = code;
this.Description = description;
this.Price = price;
}

C12, Slide 35

35

A Product class with three required properties


public class Product
{
public required string Code { get; set; }
public required string Description { get; set; }
public required decimal Price { get; set; }
...
}

C12, Slide 36

36

18
4/16/2024

How to use the SetsRequiredMembers attribute


using System.Diagnostics.CodeAnalysis;
...
public class Product
{
public Product() { }

[SetsRequiredMembers]
public Product(string code, string description,
decimal price)
{
Code = code;
Description = description;
Price = price;
}

public required string Code { get; set; }


public required string Description { get; set; }
public required decimal Price { get; set; }
...
}

C12, Slide 37

37

Nested if statements that test an object’s type


and property value
private static decimal GetDiscountPercent(Object o)
{
decimal discountPercent = .0m;
if (o is Product p)
{
if (p.Category == ".NET")
discountPercent = .1m;
else if (p.Category == "Java")
discountPercent = .2m;
}
return discountPercent;
}

C12, Slide 38

38

19
4/16/2024

A switch statement that tests an object’s type


and property value
private static decimal GetDiscountPercent(Object o)
{
switch (o)
{
case Product p when p.Category == ".NET":
return .1m;
case Product p when p.Category == "Java":
return .2m;
default:
return .0m;
}
}

C12, Slide 39

39

A switch expression that uses a property pattern


to test an object’s type and property value
private static decimal GetDiscountPercent(Object o) =>
o switch
{
Product { Category: ".NET" } => .1m,
Product { Category: "Java" } => .2m,
_ => .0m
};

C12, Slide 40

40

20
4/16/2024

A method that tests two types of objects


private static decimal GetDiscountPercent(Object o) =>
o switch
{
Product { Category: ".NET" } => .1m,
Product { Category: "Java" } => .2m,
Product { Category: "Web" } => .3m,
Product { Category: "Mainframe"} => .4m,
Vendor { DiscountType: "Quantity"} => .2m,
Vendor { DiscountType: "Terms", Terms: 30 } => .3m,
_ => .0m
};

C12, Slide 41

41

A method that tests a specific type of object


private static decimal GetDiscountPercent(Product p) =>
p switch
{
{ Category: ".NET" } => .1m,
{ Category: "Java" } => .2m,
_ => .0m
};

C12, Slide 42

42

21
4/16/2024

How to refer to a nested property


in a property pattern
Prior to C# 10.0
private static decimal GetTaxPercent(Object o) => o switch
{
Vendor { State: { StateCode: "CA" } } => 7.5m,
Vendor { State: { StateCode: "NY" } } => 6m,
...
_ => .0m
};

C# 10.0 and later


private static decimal GetTaxPercent(Object o) => o switch
{
Vendor { State.StateCode: "CA" } => 7.5m,
Vendor { State.StateCode: "NY" } => 6m,
...
_ => .0m
};

C12, Slide 43

43

A Product structure
public struct Product
{
public Product(string code, string description,
decimal price)
{
this.Code = code;
this.Description = description;
this.Price = price;
}
public string Code { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }

public string GetDisplayText(string sep) =>


$"{Code}{sep}{Price.ToString("c")}{sep}{Description}";
}

C12, Slide 44

44

22
4/16/2024

A read-only Product structure (C# 7.2 and later)


public readonly struct Product
{
public Product(string code, string description,
decimal price) {...}

public string Code { get; }


public string Description { get; }
public decimal Price { get; }

public string GetDisplayText(string sep) =>


$"{Code}{sep}{Price.ToString("c")}{sep}{Description}";
}

C12, Slide 45

45

Code that works with an instance


of a structure type
// Create an instance of the Product structure
// using the default constructor
Product p = new();

// Assign values to each property


p.Code = "C#";
p.Description = "Murach's C#";
p.Price = 59.50m;

// Call a method
string msg = p.GetDisplayText("\n");

C12, Slide 46

46

23
4/16/2024

Code that initializes properties


With a constructor
Product p = new("C#", "Murach's C#", 59.50m);

With an object initializer


Product p = new() {Code="C#",Description="Murach's C#",
Price = 59.50m};

C12, Slide 47

47

Code that creates and compares two structures


Product p1 = new("C#", "Murach's C#", 59.50m);
Product p2 = new("C#", "Murach's C#", 59.50m);
bool isEqual = p1.Equals(p2); // isEqual is true

p2.Price = 61.50m;
isEqual = p1.Equals(p2); // isEqual is false

C12, Slide 48

48

24
4/16/2024

Code that copies a structure and changes a value


Product product = new("C#", "Murach's C#", 59.50m);
Product copy = product;
copy.Price = 61.50m;

C12, Slide 49

49

A Product record
public record Product
{
public Product(string code, string description,
decimal price) {...}

public string Code { get; set; }


public string Description { get; set; }
public decimal Price { get; set; }

public string GetDisplayText(string sep) =>


$"{Code}{sep}{Price.ToString("c")}{sep}{Description}";
}

C12, Slide 50

50

25
4/16/2024

Code that creates and compares


two record instances
Product p1 = new("C#", "Murach's C#", 59.50m);
Product p2 = new("C#", "Murach's C#", 59.50m);
bool isEqual = p1.Equals(p2); // isEqual is true

p2.Price = 61.50m;
isEqual = p1 == p2; // isEqual is false

C12, Slide 51

51

A read-only Product record


public record Product(string Code, string Description,
decimal Price);

C12, Slide 52

52

26
4/16/2024

Code that copies an instance of a read-only


record and changes a value
Product product = new("C#", "Murach's C#", 59.50m);

By passing the values of the original


to the constructor of the copy
Product copy1 =
new(product.Code, product.Description, 61.50m);

By using the with keyword


Product copy2 = product with { Price = 61.50m };

C12, Slide 53

53

A Product record struct


public record struct Product
{
public Product(string code, string description,
decimal price) {...}

public string Code { get; set; }


public string Description { get; set; }
public decimal Price { get; set; }

public string GetDisplayText(string sep) =>


$"{Code}{sep}{Price.ToString("c")}{sep}{Description}";
}

C12, Slide 54

54

27
4/16/2024

Code that creates and compares


two record struct instances
Product p1 = new("C#", "Murach's C#", 59.50m);
Product p2 = p1; // makes a copy
bool isEqual = p1.Equals(p2); // isEqual is true

p2.Price = 61.50m; // changes p2 but not p1


isEqual = p1 == p2; // isEqual is false

C12, Slide 55

55

A read-only Product record struct


public readonly record struct Product(string Code,
string Description, decimal Price);

C12, Slide 56

56

28
4/16/2024

When to use classes, structures, records,


and record structs
 Use a class when your object is complex, has many methods, or
you need to create a hierarchy.
 Use a structure when your object primarily stores data and is
small enough to copy efficiently.
 Use a record when your object primarily stores data and is small
enough to copy efficiently.
 Use a record struct when your object primarily stores data, is
small enough to copy efficiently, and you want improved
equality comparison features and performance.

C12, Slide 57

57

The Product Maintenance app with a record


The Product record
public record Product(string Code, string Description,
decimal Price)
{
public string GetDisplayText() => GetDisplayText(", ");
public string GetDisplayText(string sep) =>
$"{Code}{sep}{Price.ToString("c")}{sep}{Description}";
}

The Save button event handler for the New Product form
private void btnSave_Click(object sender, EventArgs e)
{
if (IsValidData())
{
product = new(txtCode.Text, txtDescription.Text,
Convert.ToDecimal(txtPrice.Text));
this.Close();
}
}

C12, Slide 58

58

29
4/16/2024

The Product Maintenance app (continued)


The Add button event handler for the Maintenance form
private void btnAdd_Click(object sender, EventArgs e)
{
frmNewProduct newProductForm = new();
Product product = newProductForm.GetNewProduct();
if (product != null)
{ if (products.Contains(product)) {
MessageBox.Show(
"A product with values " +
product.GetDisplayText() +
" is already in list.", "Unable to add");
}
else {
products.Add(product);
ProductDB.SaveProducts(products);
FillProductListBox();
}
}
}

C12, Slide 59

59

30

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy