{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "5b20420f-c739-4683-ad0e-1cb5a3ae73c1",
   "metadata": {},
   "source": [
    "```{index} class; Contact\n",
    "```\n",
    "\n",
    "(class)=\n",
    "\n",
    "# Class Syntax"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c91dd9d6",
   "metadata": {},
   "source": "## Overview\n\nTo understand class and object-oriented programming (OOP), some important basic concepts learn first inlcude:\n\n- **Class**: A class is a blueprint, prototype, or template.\n- **Class Members**: In C#, a class contains members, which include **fields**, properties, **methods**, and events.\n- **Class Instance**: An `object` is an `instance` of a class. Namely, an object is created based on a\n  class and therefore is an instance of that class. An object can be created using the `new` keyword.\n\nThere are related terminology that you will see about class and OOP:\n\n- **Field**: A field is a variable of any type that is declared directly in a class or struct. Fields are\n  members of their containing type. A field stores a piece of data within an object. It acts like a\n  variable and may have a different value for each instance of a type. [1]\n- **Property**: Properties expose fields. Fields should (almost always) be kept private to a class and accessed via\n  get and set properties.\n- The **this** Keyword: In C#, the this keyword refers to the current instance of a class.\n- **Reference Types**: A type that is defined as a class is a reference type. Other types include: interface, struct, delegate, or enum.\n- **Constructor**: In C#, a constructor is called when an object is created to set default values. A constructor must have the\n  **same name** as the enclosing class. Using constructor is not obligatory in C#. If no constructors are specified in a class, the compiler\n  automatically creates a parameterless constructor."
  },
  {
   "cell_type": "markdown",
   "id": "3004c5e4",
   "metadata": {},
   "source": "## Declaring Classes\n\nTo declare a class, you need to use the `class` keyword and give a unique `identifier` (name) to the class. For example,\nyou want to create a customer class to include some data and methods in one unit:\n\n```csharp\n// [access modifier] - [class] - [identifier]\n\npublic class Customer\n{\n   // Fields, properties, methods and events go here...\n}\n```\n\nAttributes to be considered when creating a class include:\n\n- Access Modifiers: The default access for a class type is internal. Basic levels of access for a class include [2] :  \n  - **public**: Access is not restricted. Anyone code can create instances of this class.\n  - **protected**: Access is limited to the containing class or types derived from the containing class.\n  - **internal**: Access is limited to the current assembly. [3]\n  - **private**: Access is limited to the containing type.\n\n- Class Identifier: A unique name for the class. An identifier is the name you assign to a type (class, interface, struct, delegate, or enum),\n  member, variable, or namespace. An identifier begins with a letter or underscore. As a convention, use PascalCase for class names and method names.\n\n- Class Body: The class body is surrounded by { }. The behavior and data are defined in the class body, including **fields**, properties, **methods**, and events on a class and\n  are collectively referred to as **class members**.\n\n- Base Class or Super Class: Optional. Name of the class’s superclass; preceded by a colon (:).\n\n- Interfaces: Interface names implemented by the class; preceded by a colon (:)."
  },
  {
   "cell_type": "markdown",
   "id": "6d3aa324",
   "metadata": {},
   "source": "## Using a Class\n\nIn the following example, there is a class called `Program` with a Main method. We define another class\ncalled `DoMath` and then, in the Main method of the Program class, 1) instantiate an object of the DoMath class by\nusing the `new` keyword and 2) use the dot notation (`.`) to access a method defined in DoMath:\n\n    internal class Program\n    {\n       static void Main(string[] args)\n       {\n          DoMath doMath = new DoMath();    // create an object using the new keyword\n          int aSum = doMath.Sum(2, 2);     // use the [object].[method] syntax to use the methods\n          Console.WriteLine(aSum);         // output 4\n       }\n    }\n\n    class DoMath                           // class accessability level is default to internal\n    {\n       public int Sum(int num1, int num2)\n       {\n          var total = num1 + num2;\n          return total;\n       }\n    }\n\nIn addition to store data as local variables and call methods in the same class,\nnow we have alternatives for storing and accessing data in the methods within\na new class that we write. Just like using the `UI` class or `Random` class, we\nnow can better design, extend, and organize program functionalities.\n\nWhen you use classes like StreamReader, you create a new StreamReader object using the `new`\nkeyword and then use the `ReadLine` method (example in csharprepl):\n\n    > StreamReader reader = new StreamReader(\"ui.cs\");\n    > string line = reader.ReadLine();\n    > line\n    \"using System;\"\n    >\n\nAs you can see, we are using the `member access operator (.)` to access a member\nof a namespace or a type. Calls to instance methods are always attached to a specific object.\nThat has always been the part through the `.` of\n\n> *object*`.`*method*`(` … `)`\n\n```{index} OOP; instance variable\n```\n\n% Constructor\n\n% Instance Variables\n\n% ———————-"
  },
  {
   "cell_type": "markdown",
   "id": "6bdc089e",
   "metadata": {},
   "source": "```{index} OOP; constructor\n```\n\n## Constructors\n\nThe constructor is a special method in the class:\n\n1.  Its `name` is the same as the name of its type. For example, if we create a class named `Contact`, then the\n    constructor method is also called `Contact`.\n2.  Its method `signature` includes only an optional access modifier, the method name, and its parameter list\n3.  Its method `signature` has `no return type` (and *no* `static`). Implicitly you are creating a default object from the class.\n4.  The constructor can have parameters like a regular method. That means giving values to its fields. For example,\n    you may want to store this *state* (the current condition of a system, such as the values of the variables) in\n    instance variables `name`, `phone` and `email` if you are creating a Contact type:\n\n```{literalinclude} ../../examples/contact1/contact1.cs\n:end-before: getter\n:start-after: constructor\n```\n\nWhile the local variables in the formal parameters disappear after the constructor terminates,\nwe want the data to live on as the state of the object. In order to remember state after the\nconstructor terminates, we must *make sure the information gets into the instance variables*\nfor the object. This is the basic operation of most constructors: Copy desired formal\nparameters in to initialize the state in the fields. That is all our simple\ncode above does.\n\nTo further explain how constructors work, take a look at the following code:\n\n    internal class Program\n    {\n       static void Main(string[] args)\n       {\n          CheckID check = new CheckID(\"taylor swift\");\n       }\n    }\n\n    class CheckID\n    {\n       public string name;           // this is an instance field (variable)\n       public CheckID(string name)\n       {\n          this.name = name;          // The \"this\" keyword refers to the current instance of the class\n       }\n\n       public void PrintResult()\n       {\n          // ... if ID for this name exists ...\n          Console.WriteLine($\"{name} has an existing ID!\"); // using the \"name\" variable in method\n       }                             // output \"taylor swift has an existing ID!\"\n       // ....\n       // ....\n    }\n\n% Note that `name`, `phone` and `email` are *not* declared as\n\n% local variables. They refer to the *instance* variables, but we are *not* using\n\n% full object notation: an object reference and a\n\n% dot, followed by the field.\n\n% So far always we have always been referring to a built-in type of object\n\n% defined in a different class, like `arrayObject.Length`.\n\n% The constructor is *creating* an object,\n\n% and the use of the bare instance variable names is understood to be giving\n\n% values to the instance variables in this Contact object\n\n% that is being constructed.\n\n% Inside a constructor\n\n% and also inside an instance method\n\n% (discussed below)\n\n% C# allows this shorthand notation without `someObject.`."
  },
  {
   "cell_type": "markdown",
   "id": "faa514d1",
   "metadata": {},
   "source": "```{index} OOP; instance method\n```\n\n## Static Classes & Methods\n\nIn some conditions you may want to create **static classes** that provide static methods without\ninstantiation. That means you do not need to use the `new` operator keyword to create a variable\nof the class type. Also, without the class instance variable, you access the members of a static\nclass by using the class name itself. For example, if you have a static class called SomeMath:\n\n    static class SomeMath\n    {\n       public static int Sum(int a, int b)    // a public static method\n       {\n          return a + b;\n       }\n    }\n\nTo use the Sum method in the SomeMath class, you call it directly without creating a new object:\n\n    internal class Program\n    {\n       static void Main(string[] args)\n       {\n          int aSum = SomeMath.Sum(2, 2);\n          Console.WriteLine(aSum);      // output 4\n       }\n    }\n\nAs another example, in the .NET Class Library, the `static` [System.Math](https://learn.microsoft.com/en-us/dotnet/api/system.math)\nclass contains methods that perform mathematical operations, without any requirement to store or\nretrieve data that is unique to a particular instance of the [Math](https://learn.microsoft.com/en-us/dotnet/api/system.math)\nclass. You can use the math methods directly in your code by referring to the static class name `Math`:\n\n    double dub = -3.14;\n    Console.WriteLine(Math.Abs(dub));               // 3.14\n    Console.WriteLine(Math.Floor(dub));             // -4\n    Console.WriteLine(Math.Round(Math.Abs(dub)));   // 3"
  },
  {
   "cell_type": "markdown",
   "id": "2dbfe984-a25a-4b83-97a2-571b7757cdde",
   "metadata": {},
   "source": [
    "```{rubric} Footnotes\n",
    "```\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "polyglot-notebook"
  },
  "polyglot_notebook": {
   "kernelInfo": {
    "defaultKernelName": "csharp",
    "items": [
     {
      "aliases": [],
      "name": "csharp"
     }
    ]
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}