From 804adb3b89bc02a3ec38c2550f70d78c83d0d0cc Mon Sep 17 00:00:00 2001 From: Timo Hocker Date: Sun, 24 May 2020 17:04:37 +0200 Subject: [PATCH] more lessons --- .vscode/settings.json | 6 +++ README.md | 3 +- cpp/inheritance/README.md | 17 +++++++ cpp/inheritance/animal.cpp | 11 +++++ cpp/inheritance/animal.h | 12 +++++ cpp/inheritance/cat.cpp | 9 ++++ cpp/inheritance/cat.h | 12 +++++ cpp/inheritance/dog.cpp | 9 ++++ cpp/inheritance/dog.h | 12 +++++ cpp/inheritance/main.cpp | 12 +++++ java/inheritance/Animal.java | 11 +++++ java/inheritance/Cat.java | 17 +++++++ java/inheritance/Dog.java | 14 ++++++ java/inheritance/Program.java | 9 ++++ java/inheritance/README.md | 8 ++++ lessons/Encapsulation.md | 32 ++++++++++++++ lessons/Inheritance.md | 15 +++++++ rust/Inheritance.md | 12 +++++ typescript/inheritance/README.md | 8 ++++ typescript/inheritance/animal.ts | 11 +++++ typescript/inheritance/cat.ts | 13 ++++++ typescript/inheritance/dog.ts | 11 +++++ typescript/inheritance/index.ts | 8 ++++ typescript/inheritance/package.json | 11 +++++ typescript/inheritance/tsconfig.json | 66 ++++++++++++++++++++++++++++ 25 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json create mode 100644 cpp/inheritance/README.md create mode 100644 cpp/inheritance/animal.cpp create mode 100644 cpp/inheritance/animal.h create mode 100644 cpp/inheritance/cat.cpp create mode 100644 cpp/inheritance/cat.h create mode 100644 cpp/inheritance/dog.cpp create mode 100644 cpp/inheritance/dog.h create mode 100644 cpp/inheritance/main.cpp create mode 100644 java/inheritance/Animal.java create mode 100644 java/inheritance/Cat.java create mode 100644 java/inheritance/Dog.java create mode 100644 java/inheritance/Program.java create mode 100644 java/inheritance/README.md create mode 100644 rust/Inheritance.md create mode 100644 typescript/inheritance/README.md create mode 100644 typescript/inheritance/animal.ts create mode 100644 typescript/inheritance/cat.ts create mode 100644 typescript/inheritance/dog.ts create mode 100644 typescript/inheritance/index.ts create mode 100644 typescript/inheritance/package.json create mode 100644 typescript/inheritance/tsconfig.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8395b53 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "system_error": "cpp", + "xlocale": "cpp" + } +} \ No newline at end of file diff --git a/README.md b/README.md index ebadcfd..f5c983e 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ Lessons: - [instanciating objects, accessing attributes and methods](./lessons/Instances.md) - [creating a class](./lessons/Classes.md) - [constructors](./lessons/Constructors.md) -- [inheritance](./lessons/Inheritance.md) - [encapsulation](./lessons/Encapsulation.md) +- [inheritance](./lessons/Inheritance.md) <-- - [properties](./lessons/Properties.md) - [polymorphism](./lessons/Polymorphism.md) @@ -24,3 +24,4 @@ Work in progress: - virtual classes - interfaces - Factories +- Generics diff --git a/cpp/inheritance/README.md b/cpp/inheritance/README.md new file mode 100644 index 0000000..62d54a2 --- /dev/null +++ b/cpp/inheritance/README.md @@ -0,0 +1,17 @@ +# Inheritance + +c++ also allows to inherit from multiple base classes at once, but that is a +little to complicated for this lesson. + +Relevant files: + +- [main.cpp](./index.cpp) + +- [animal.h](./animal.h) +- [animal.cpp](./animal.cpp) + +- [cat.h](./cat.h) +- [cat.cpp](./cat.cpp) + +- [dog.h](./dog.h) +- [dog.cpp](./dog.cpp) diff --git a/cpp/inheritance/animal.cpp b/cpp/inheritance/animal.cpp new file mode 100644 index 0000000..09af842 --- /dev/null +++ b/cpp/inheritance/animal.cpp @@ -0,0 +1,11 @@ +#include "animal.h" +#include +#include + +animal::animal(std::string name) { + this->name = name; +} + +void animal::make_sound() { + cout << name << ":" << endl; +} diff --git a/cpp/inheritance/animal.h b/cpp/inheritance/animal.h new file mode 100644 index 0000000..df2c12f --- /dev/null +++ b/cpp/inheritance/animal.h @@ -0,0 +1,12 @@ +#pragma once + +#include +using namespace std; + +class animal +{ + public: + std::string name; + virtual void make_sound(); + animal(std::string name); +}; diff --git a/cpp/inheritance/cat.cpp b/cpp/inheritance/cat.cpp new file mode 100644 index 0000000..f5295a4 --- /dev/null +++ b/cpp/inheritance/cat.cpp @@ -0,0 +1,9 @@ +#include "cat.h" + +#include +#include + +void cat::make_sound() { + animal::make_sound(); + cout << "meow" << endl; +} diff --git a/cpp/inheritance/cat.h b/cpp/inheritance/cat.h new file mode 100644 index 0000000..142e8f9 --- /dev/null +++ b/cpp/inheritance/cat.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include "animal.h" +using namespace std; + +class cat: public animal +{ + using animal::animal; + public: + void make_sound() override; +}; diff --git a/cpp/inheritance/dog.cpp b/cpp/inheritance/dog.cpp new file mode 100644 index 0000000..f6eb9c4 --- /dev/null +++ b/cpp/inheritance/dog.cpp @@ -0,0 +1,9 @@ +#include "dog.h" + +#include +#include + +void dog::make_sound() { + cout << "doggo " << name << " says:" << endl; + cout << "woof!" << endl; +} diff --git a/cpp/inheritance/dog.h b/cpp/inheritance/dog.h new file mode 100644 index 0000000..c771d7e --- /dev/null +++ b/cpp/inheritance/dog.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include "animal.h" +using namespace std; + +class dog: public animal +{ + using animal::animal; + public: + void make_sound() override; +}; diff --git a/cpp/inheritance/main.cpp b/cpp/inheritance/main.cpp new file mode 100644 index 0000000..03ffd1d --- /dev/null +++ b/cpp/inheritance/main.cpp @@ -0,0 +1,12 @@ +#include "cat.h" +#include "dog.h" + +#include + +int main() { + dog d("buster"); + cat c("mittens"); + + d.make_sound(); + c.make_sound(); +} diff --git a/java/inheritance/Animal.java b/java/inheritance/Animal.java new file mode 100644 index 0000000..a683491 --- /dev/null +++ b/java/inheritance/Animal.java @@ -0,0 +1,11 @@ +public class Animal { + public String name; + + public Animal(String name) { + this.name = name; + } + + public void make_sound() { + System.out.println(this.name + ":"); + } +} diff --git a/java/inheritance/Cat.java b/java/inheritance/Cat.java new file mode 100644 index 0000000..8904330 --- /dev/null +++ b/java/inheritance/Cat.java @@ -0,0 +1,17 @@ +// make the class cat inherit from Animal +public class Cat extends Animal { + // java requires an explicit constructor when the supertype awaits parameters in the constructor + public Cat(String name) { + // call supertype constructor + super(name); + } + + // override make_sound + public void make_sound() { + // optional: call the parent class function + super.make_sound(); + + // add additional functionality + System.out.println("meow"); + } +} diff --git a/java/inheritance/Dog.java b/java/inheritance/Dog.java new file mode 100644 index 0000000..b52ff14 --- /dev/null +++ b/java/inheritance/Dog.java @@ -0,0 +1,14 @@ +public class Dog extends Animal { + // java requires an explicit constructor when the supertype awaits parameters in the constructor + public Dog(String name) { + // call supertype constructor + super(name); + } + + // override the method make_sound + public void make_sound() { + // implement own functionality + System.out.println("doggo " + this.name + " says:"); + System.out.println("woof!"); + } +} diff --git a/java/inheritance/Program.java b/java/inheritance/Program.java new file mode 100644 index 0000000..e7afa0e --- /dev/null +++ b/java/inheritance/Program.java @@ -0,0 +1,9 @@ +public class Program { + public static void main(String[] args) { + Dog d = new Dog("buster"); + Cat c = new Cat("mittens"); + + d.make_sound(); + c.make_sound(); + } +} diff --git a/java/inheritance/README.md b/java/inheritance/README.md new file mode 100644 index 0000000..cb954f2 --- /dev/null +++ b/java/inheritance/README.md @@ -0,0 +1,8 @@ +# Inheritance + +Relevant files: + +- [Program.java](./Program.java) +- [Animal.java](./Animal.java) +- [Cat.java](./Cat.java) +- [Dog.java](./Dog.java) diff --git a/lessons/Encapsulation.md b/lessons/Encapsulation.md index e69de29..337e4c6 100644 --- a/lessons/Encapsulation.md +++ b/lessons/Encapsulation.md @@ -0,0 +1,32 @@ +# Encapsulation + +Encapsulation is a simple lesson, this one is not gonna need any code examples. + +There are typically 3 keywords you need for encapsulation: private, protected +and public. + +## Private + +Private methods and fields are only acessible from within the same class, they +can't be read or written from outside. + +## Protected + +Protected is just like private, but descendant classes can access them. + +## Public + +Public is accessible from anywhere. + +## The static modifier + +Static is another one of those keywords, although it doesn't really control +access to fields and methods. Anything with the static keyword can be used +without an instance of the class. That means you can directly access with with +Class.property instead of creating an instance of that class first. This is used +for example in java for the main method, since it needs to be accessible without +running any of the programs code first. + +Encapsulation is not a safety feature, it's only to make clear, which properties +should be used by others. Methods like reflection and directly reading/writing +memory can still access private or protected properties. diff --git a/lessons/Inheritance.md b/lessons/Inheritance.md index e69de29..da852fe 100644 --- a/lessons/Inheritance.md +++ b/lessons/Inheritance.md @@ -0,0 +1,15 @@ +# Inheritance + +Inheritance is useful to minimize code duplicates and generalize types in base +classes. + +A Class can inherit all public and protected functions and fields from a base +class and add its own or override existing ones. Private fields and functions +still exist in the base class, but can't be acessed from the extending class. + +## Examples + +- [Java](../java/inheritance/README.md) +- [Rust](../rust/Inheritance.md) +- [C++](../cpp/inheritance/README.md) +- [JavaScript (using TypeScript)](../typescript/inheritance/README.md) diff --git a/rust/Inheritance.md b/rust/Inheritance.md new file mode 100644 index 0000000..512a6e5 --- /dev/null +++ b/rust/Inheritance.md @@ -0,0 +1,12 @@ +# Inheritance, Properties and Polymorphism + +Rust does not allow extending classes. Instead the base class is stored as a +field in the extending class. Polymorphism can then be achieved by passing the +field instead of the whole object to a function. Although casting back to the +advanced class or overriding functions is not possible. + +Properties don't exist either, like in java. But replacing them with getters and +setters is also discouraged. Quoting from a reddit post 'Expose behavior, not +state'. That means you should present functions to outside viewers and not your +plain data. An object should be able to do all its intended functions itself +without having an outside observer read its data. diff --git a/typescript/inheritance/README.md b/typescript/inheritance/README.md new file mode 100644 index 0000000..3a8a430 --- /dev/null +++ b/typescript/inheritance/README.md @@ -0,0 +1,8 @@ +# Inheritance + +Relevant files: + +- [index.ts](./index.ts) +- [animal.ts](./animal.ts) +- [cat.ts](./cat.ts) +- [dog.ts](./dog.ts) diff --git a/typescript/inheritance/animal.ts b/typescript/inheritance/animal.ts new file mode 100644 index 0000000..359af03 --- /dev/null +++ b/typescript/inheritance/animal.ts @@ -0,0 +1,11 @@ +export class Animal { + public name: string; + + public constructor(name: string) { + this.name = name; + } + + public make_sound() { + console.log(`${this.name}:`); + } +} diff --git a/typescript/inheritance/cat.ts b/typescript/inheritance/cat.ts new file mode 100644 index 0000000..07a1e6e --- /dev/null +++ b/typescript/inheritance/cat.ts @@ -0,0 +1,13 @@ +import {Animal} from './animal'; + +// make the class cat inherit from Animal +export class Cat extends Animal { + // override make_sound + public make_sound() { + // optional: call the parent class function + super.make_sound(); + + // add additional functionality + console.log('meow'); + } +} diff --git a/typescript/inheritance/dog.ts b/typescript/inheritance/dog.ts new file mode 100644 index 0000000..467f293 --- /dev/null +++ b/typescript/inheritance/dog.ts @@ -0,0 +1,11 @@ +import {Animal} from './animal'; + +export class Dog extends Animal { + + // override the method make_sound + public make_sound() { + // implement own functionality + console.log(`doggo ${this.name} says:`); + console.log('woof!'); + } +} diff --git a/typescript/inheritance/index.ts b/typescript/inheritance/index.ts new file mode 100644 index 0000000..c0e4797 --- /dev/null +++ b/typescript/inheritance/index.ts @@ -0,0 +1,8 @@ +import { Dog } from "./dog"; +import { Cat } from "./cat"; + +const d = new Dog('buster'); +const c = new Cat('mittens'); + +d.make_sound(); +c.make_sound(); diff --git a/typescript/inheritance/package.json b/typescript/inheritance/package.json new file mode 100644 index 0000000..22361fc --- /dev/null +++ b/typescript/inheritance/package.json @@ -0,0 +1,11 @@ +{ + "name": "ts-oop", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/typescript/inheritance/tsconfig.json b/typescript/inheritance/tsconfig.json new file mode 100644 index 0000000..6232546 --- /dev/null +++ b/typescript/inheritance/tsconfig.json @@ -0,0 +1,66 @@ +{ + "compilerOptions": { + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./dist", /* Concatenate and emit output to single file. */ + "outDir": "./dist", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +}