Object Oriented Programming Classes and Objects Dr. Mike Spann

Slides:



Advertisements
Similar presentations
Final and Abstract Classes
Advertisements

The Line Class Suppose you are involved in the development of a large mathematical application, and this application needs an object to represent a Line.
©The McGraw-Hill Companies, Inc. Permission required for reproduction or display. 4 th Ed Chapter Chapter 4 Defining Your Own Classes.
George Blank University Lecturer. CS 602 Java and the Web Object Oriented Software Development Using Java Chapter 4.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
1 Classes Overview l Classes as Types l Declaring Instance Variables l Implementing Methods l Constructors l Accessor and Mutator Methods.
1 Programming for Engineers in Python Autumn Lecture 5: Object Oriented Programming.
OOP in Java Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Object Oriented Programming.  OOP Basic Principles  C++ Classes  September 2004  John Edgar 22.
Differences between C# and C++ Dr. Catherine Stringfellow Dr. Stewart Carpenter.
11 Values and References Chapter Objectives You will be able to: Describe and compare value types and reference types. Write programs that use variables.
1 Using Classes Object-Oriented Programming Using C++ Second Edition 5.
Programming Languages and Paradigms Object-Oriented Programming.
Object Oriented Programming Classes and Objects Dr. Mike Spann
CSM-Java Programming-I Spring,2005 Introduction to Objects and Classes Lesson - 1.
 2003 Prentice Hall, Inc. All rights reserved. 1 Introduction to Classes and Objects Outline Introduction Classes, Objects, Member Functions and Data.
 2006 Pearson Education, Inc. All rights reserved Classes: A Deeper Look.
EE4E. C++ Programming Lecture 1 From C to C++. Contents Introduction Introduction Variables Variables Pointers and references Pointers and references.
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
Java Classes Appendix C © 2015 Pearson Education, Inc., Hoboken, NJ. All rights reserved.
Lecture Set 11 Creating and Using Classes Part B – Class Features – Constructors, Methods, Fields, Properties, Shared Data.
Copyright © 2002, Systems and Computer Engineering, Carleton University a-JavaReview.ppt * Object-Oriented Software Development Unit.
Session 08 Module 14: Generics and Iterator Module 15: Anonymous & partial class & Nullable type.
Constructors CMSC 202. Object Creation Objects are created by using the operator new in statements such as… The following expression invokes a special.
Methods in Java. Program Modules in Java  Java programs are written by combining new methods and classes with predefined methods in the Java Application.
1 Chapter 8 – Classes and Object: A Deeper Look Outline 1 Introduction 2 Implementing a Time Abstract Data Type with a Class 3 Class Scope 4 Controlling.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 223 – Advanced Data Structures C++ Review Part-I.
ADTs and C++ Classes Classes and Members Constructors The header file and the implementation file Classes and Parameters Operator Overloading.
EE2E1. JAVA Programming Lecture 3 Java Programs and Packages.
An Object-Oriented Approach to Programming Logic and Design Chapter 3 Using Methods and Parameters.
More About Objects and Methods Chapter 5. Outline Programming with Methods Static Methods and Static Variables Designing Methods Overloading Constructors.
EE2E1. JAVA Programming Lecture 3 Inheritance. Contents Base classes and derived classes Base classes and derived classes Protected scope Protected scope.
Visual C# 2012 for Programmers © by Pearson Education, Inc. All Rights Reserved.
Chapter 8 Objects and Classes Object Oriented programming Instructor: Dr. Essam H. Houssein.
1 Chapter Four Creating and Using Classes. 2 Objectives Learn about class concepts How to create a class from which objects can be instantiated Learn.
Classes. Constructor A constructor is a special method whose purpose is to construct and initialize objects. Constructor name must be the same as the.
Method Overloading  Methods of the same name can be declared in the same class for different sets of parameters  As the number, types and order of the.
Object Oriented Programming Generic Collections and LINQ Dr. Mike Spann
Classes Modeling the Object. Objects model the world Classes are programmer defined types that model the parts of a system Class serve as blueprints for.
Chapter 10: Classes and Data Abstraction. Objectives In this chapter, you will: Learn about classes Learn about private, protected, and public members.
UMass Lowell Computer Science Java and Distributed Computing Prof. Karen Daniels Fall, 2000 Lecture 9 Java Fundamentals Objects/ClassesMethods Mon.
CS305j Introduction to Computing Classes II 1 Topic 24 Classes Part II "Object-oriented programming as it emerged in Simula 67 allows software structure.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
More about Java Classes Writing your own Java Classes More about constructors and creating objects.
Inheritance and Class Hierarchies Chapter 3. Chapter Objectives  To understand inheritance and how it facilitates code reuse  To understand how Java.
Quick Review of OOP Constructs Classes:  Data types for structured data and behavior  fields and methods Objects:  Variables whose data type is a class.
Object Oriented Programming. OOP  The fundamental idea behind object-oriented programming is:  The real world consists of objects. Computer programs.
Chapter 10: Classes and Data Abstraction. Classes Object-oriented design (OOD): a problem solving methodology Objects: components of a solution Class:
Chapter 1 C++ Basics Review (Section 1.4). Classes Defines the organization of a data user-defined type. Members can be  Data  Functions/Methods Information.
Java & C++ Comparisons How important are classes and objects?? What mechanisms exist for input and output?? Are references and pointers the same thing??
CS 116 Lecture 1 John Korah Contains content provided by George Koutsogiannakis & Matt Bauer.
OOP Basics Classes & Methods (c) IDMS/SQL News
Object-Oriented Programming: Classes and Objects Chapter 1 1.
Structure A Data structure is a collection of variable which can be same or different types. You can refer to a structure as a single variable, and to.
Object Based Programming Chapter 8. 2 Contrast ____________________ Languages –Action oriented –Concentrate on writing ________________ –Data supports.
Sadegh Aliakbary Sharif University of Technology Fall 2010.
Object Oriented Programming. Constructors  Constructors are like special methods that are called implicitly as soon as an object is instantiated (i.e.
EE2E1. JAVA Programming Lecture 4 Interfaces. Contents Interfaces – introduction Interfaces – introduction Example – generic sorting Example – generic.
Topic: Classes and Objects
Static data members Constructors and Destructors
Examples of Classes & Objects
Object-Oriented Programming: Classes and Objects
Chapter 3: Using Methods, Classes, and Objects
Object-Oriented Programming: Classes and Objects
Lecture 2 Objects and Classes
Classes & Objects: Examples
Classes and Objects.
Java Programming Language
Dr. R Z Khan Handout-3 Classes
Creating and Using Classes
Presentation transcript:

Object Oriented Programming Classes and Objects Dr. Mike Spann

Contents Introducing Object Oriented Programming Introducing Object Oriented Programming Classes, Types and Objects Classes, Types and Objects Building our own classes Building our own classes Constructors Constructors Properties Properties Implementation/Interface and encapsulation Implementation/Interface and encapsulation Method arguments – call by value and by reference Method arguments – call by value and by reference Delegates and lambda expressions Delegates and lambda expressions Summary Summary

Introducing Object Oriented Programming Object oriented programming (OOP) is THE programming methodology for designing complex systems Object oriented programming (OOP) is THE programming methodology for designing complex systems OOP essentially is about the use of re-useable software components called objects OOP essentially is about the use of re-useable software components called objects These objects can be prebuilt by third party vendors to ‘plug in’ to our application or can be developed by ourselves These objects can be prebuilt by third party vendors to ‘plug in’ to our application or can be developed by ourselves  Perhaps building on existing objects

Introducing Object Oriented Programming There are good reasons why building our application out of such objects has major advantages There are good reasons why building our application out of such objects has major advantages  We can abstract out the complex state and behaviour of individual objects  Only the interface between the objects in our application is important  We can use prebuilt objects such as FCL objects  We are able to extend these objects to meet our own needs

Introducing Object Oriented Progr amming Drive Transmission Gearbox Engine Electronics

Classes, Types and Objects The Framework Class Library (FCL) consists of classes, interfaces structures and enumerated types The Framework Class Library (FCL) consists of classes, interfaces structures and enumerated types  Collectively known as types  We have already seen some examples of classes  Console, Form, Array  Classes are reference types  Value types are known as structures We can create our own classes, interfaces, structures and enumerated types We can create our own classes, interfaces, structures and enumerated types

Classes, Types and Objects The process of using a type to create an object is called instantiation The process of using a type to create an object is called instantiation In C#, C++, and Java the new keyword is used In C#, C++, and Java the new keyword is used We could create many Car objects but there is only one Car class We could create many Car objects but there is only one Car class Car myCar = new Car(“Peugeot 207”); ClassObject

Classes, Types and Objects Car myCar = new Car(“Peugeot 207”); Car myColleaguesCar = new Car(“Ford Focus”); myCar myColleaguesCar Peugeot 207 Ford Focus Car

Building our own classes We can easily build our own classes which comprise methods and fields We can easily build our own classes which comprise methods and fields  Simply stated, methods are functions which describe the behaviour of objects of the class  Fields are themselves types (either objects or primitive types) which describe the state of the object We create a class using the class{} clause We create a class using the class{} clause class myClass { // Methods and fields }

Building our own classes The class can optionally exist in its own namespace The class can optionally exist in its own namespace  The full class name then becomes name.myClass  If no namespace is specified, it exists in the default namespace namespace name { class myClass { // Methods and fields }

Building our own classes A StudentInfo class used to store student records information A StudentInfo class used to store student records information 2 (public) methods 2 (public) methods  StudentInfo(..) – a method with the same name as the class, known as a constructor  Used for initializing StudentInfo objects  printStudentInfo()  Outputs the records information to the console 3 (private) instance fields 3 (private) instance fields  name  idNumber  address

Building our own classes using System; public class StudentInfo { public StudentInfo(string n, int id, string a) { name=n; idNumber=id; address=a; } public void printStudentInfo() { Console.WriteLine(name + " " + idNumber + " " + address); } private string name; private int idNumber; private string address; }

Building our own classes Keyword private means only methods in the StudentInfo class can access these fields Keyword private means only methods in the StudentInfo class can access these fields Keyword public means the method can be called from any other method in any other class Keyword public means the method can be called from any other method in any other class

Building our own classes StudentInfo String name int idNumber String address private public StudentInfo() printStudentInfo() Accessed only by Accessed from anywhere

Building our own classes using System; class StudentInfoTest { static void Main(string[] args) { StudentInfo si1=new StudentInfo("John Smith", 3429, "21 Bristol Rd"); StudentInfo si2=new StudentInfo("Alan Jones", 5395, "15 Bournbrook Rd"); si1. printStudentInfo(); si2.printStudentInfo(); }

Building our own classes So far in the StudentInfo class, we have 3 private instance fields So far in the StudentInfo class, we have 3 private instance fields  name  idNumber  address These instance fields are known as non- static instance fields These instance fields are known as non- static instance fields  Each StudentInfo object has its own separate copy of these three fields

Building our own classes We can also have static instance fields which represent class wide information We can also have static instance fields which represent class wide information  For example we might want to keep the total number of students registered as a static field of StudentInfo  Not sensible to keep this in each StudentInfo object  Can be accessed by methods of StudentInfo  But not vice versa – static methods cannot access non-static instance fields!

public class StudentInfo { public StudentInfo(string n, int id, string a) { name=n; idNumber=id; address=a; } public void printStudentInfo() { Console.WriteLine(name + " " + idNumber + " " + address); Console.WriteLine(numberRegistered + " students “); } private static int numberRegistered; private string name; private int idNumber; private string address; }

Building our own classes class StudentInfoTest { static void Main(string[] args) { StudentInfo si1=new StudentInfo("John Smith",3429, "21 Bristol Rd"); StudentInfo si2=new StudentInfo("Alan Jones", 5395, "15 Bournbrook Rd"); si1.printStudentInfo(); }

Building our own classes StudentInfo s1=new StudentInfo(....); StudentInfo s2=new StudentInfo(....); s1s2 name=“John Smith" idNumber=3429 address="21 Bristol Rd" name=“Alan Jones“ idNumber= 5395 address="15 Bournbrook Rd " class StudentInfo private String name; private int idNumber; private String address private static numberRegistered=2;

Constructors A constructor is a special method of a class used to initialize the fields of each object created A constructor is a special method of a class used to initialize the fields of each object created  The C# compiler knows you are defining a constructor method when you give a method the exact same name as the type itself The constructor method is automatically called by the runtime when an instance is created The constructor method is automatically called by the runtime when an instance is created It is possible for constructors to be overloaded so that an object can be created with a variety of starting data It is possible for constructors to be overloaded so that an object can be created with a variety of starting data

Constructors using System; public class StudentInfo { public StudentInfo() {} // default constructor public StudentInfo(string n, int id, string a) { name=n; idNumber=id; address=a; } public void printStudentInfo() { Console.WriteLine(name + " " + idNumber + " " + address); } private string name; private int idNumber; private string address; }

Constructors using System; public class StudentInfoTest { public static void Main(string[] args) { StudentInfo s1=new StudentInfo(“John Smith”,12345, “53 Bristol Rd”); StudentInfo s2=new StudentInfo(); // Default constructor }

Constructors The default constructor makes default initializations for type The default constructor makes default initializations for type  Reference types default to null  Integers default to zero  It is automatically provided by the compiler should no other constructor be given Normally, use is made of the this reference to enforce user defined default initializations Normally, use is made of the this reference to enforce user defined default initializations  this is an implicit reference to the outer object

Constructors StudentInfo String name int idNumber String address private public StudentInfo( ) printStudentInfo( ) this

Constructors using System; public class StudentInfo { public StudentInfo() {this(“No name”, 0, “Birmingham University”} public StudentInfo(string n, int id, string a) { name=n; idNumber=id; address=a; } public void printStudentInfo() { Console.WriteLine(name + " " + idNumber + " " + address); } private string name; private int idNumber; private string address; }

Properties Properties are class members which can be accessed using field access syntax, but they are really method calls Properties are class members which can be accessed using field access syntax, but they are really method calls  Essentially more convenient syntax than method calls A property has a name and a type, and comes with a read function and a write function named get and set respectively A property has a name and a type, and comes with a read function and a write function named get and set respectively  Generally for each private field, we declare one public property

public class StudentInfo { public StudentInfo(string n, int id, string a) { name=n; idNumber=id; address=a; } public void printStudentInfo() { Console.WriteLine(name + " " + idNumber + " " + address); } public string Name { get { return name; } set { name = value; } } public string Address { get { return address; } set { address = value; } } public int ID { get { return idNumber; } set { idNumber = value; } } private string name; private int idNumber; private string address; }

class StudentInfoTest { static void Main(string[] args) { StudentInfo si1=new StudentInfo(null, 0, null); StudentInfo si2=new StudentInfo("Alan Jones", 5395,"15 Bournbrook Rd"); // Access through properties // Uses set{} si1.ID = 3429; si1.Name = "John Smith"; si1.Address = "21 Bristol Rd"; // Uses get{} int id = si2.ID; string name=si2.Name; string address=si2.Address; } Properties

We could validate the data before setting it, for example: We could validate the data before setting it, for example: public int ID { get { return idNumber; } set { if (value > 0) idNumber = value; else idNumber = -1; }

Implementation/Interface and encapsulation Generally, instance fields are private Generally, instance fields are private  They represent the implementation of the class (or the object internal state) Methods are generally public Methods are generally public  They represent the interface to the class  The define how objects can be used The separation of a class into public/private is a key feature of object-oriented programming The separation of a class into public/private is a key feature of object-oriented programming  Sometimes known as encapsulation

Implementation/Interface and encapsulation The implementation of a class is specified in the private instance fields The implementation of a class is specified in the private instance fields  They are hidden from outside the class The interface to the class is specified by the public methods The interface to the class is specified by the public methods  They can be accessed from anywhere The implementation may change but the interface must stay the same The implementation may change but the interface must stay the same

Implementation/Interface and encapsulation Example Example  Class Point represents the position in the 2D (x-y) plane  The x and y coordinates are accessed through the properties X and Y  Note that these are declared as public

Implementation/Interface and encapsulation public class Point { public Point(int x, int y) { xpos = x; ypos = y; } public int X { get{ return xpos; } set { xpos=value; } } public int Y { get{ return ypos; } set { ypos=value; } } private int xpos, ypos; }

Implementation/Interface and encapsulation We can use this class in an application to represent a polygon as an array of points (vertices) We can use this class in an application to represent a polygon as an array of points (vertices)  Could be for a computer graphics application For example, to compute the perimeter of the polygon, we need to access the coordinates of the vertices For example, to compute the perimeter of the polygon, we need to access the coordinates of the vertices  We do this through the properties X and Y

Implementation/Interface and encapsulation class Polygon { public Polygon() {…} public double perimeter() { double pm=0; int nn; double pm=0; int nn; for (int n=1; n<numVertices; n++) for (int n=1; n<numVertices; n++) {nn=n%numVertices; // Access vertices coordinates through properties int xv1= vertices[n-1].X; int xv1= vertices[n-1].X; int yv1=vertices[n-1]. Y; int xv=vertices[nn].X; int xv=vertices[nn].X; int yv=vertices[nn].Y; pm+=(Math.sqrt((xv1-xv)*(xv1-xxv)+(yv1-yv)*(yv1-yv))); pm+=(Math.sqrt((xv1-xv)*(xv1-xxv)+(yv1-yv)*(yv1-yv))); } return pm; return pm;} private Point[] vertices; private int numVertices; }

Implementation/Interface and encapsulation The idea behind encapsulation is that changing the implementation of Point will not change the implementation of the Polygon class because Point objects are accessed through public properties or methods The idea behind encapsulation is that changing the implementation of Point will not change the implementation of the Polygon class because Point objects are accessed through public properties or methods  The users of Point do not even need to know about it  Point is a re-useable software component Example – we can implement Point objects using a polar coordinate representation Example – we can implement Point objects using a polar coordinate representation

public class Point { public Point(int x, int y) { r=System.Math.Sqrt(x*x+y*y) theta=Math.Atan2((double)y,(double)x); } public double X { get{return (r*Math.Cos(theta));} } public double Y { get { return (r * Math.Sin(theta)); } } private double r; private double theta; }

Method arguments – call by value and by reference We have already seen that we can have reference types (usually references to objects) and value type (usually primitive types) We have already seen that we can have reference types (usually references to objects) and value type (usually primitive types) There are similarly two ways to pass arguments to class methods There are similarly two ways to pass arguments to class methods  Pass by value  Pass by reference

Method arguments – call by value and by reference As in C++ and Java, pass by value creates a local copy in the called method As in C++ and Java, pass by value creates a local copy in the called method  The called method can’t change the value of the argument in the calling method Pass by reference involves passing a (copy) of the argument (object) reference into the called method Pass by reference involves passing a (copy) of the argument (object) reference into the called method  The called method can then change the state of the argument (object) in the calling method Also C# provides a keyword out to create an output parameter Also C# provides a keyword out to create an output parameter  This indicates that the uninitialized arguments will be passed to the called method by reference which will assign a value to the original variable from the calling method

Method arguments – call by value and by reference public class Square { public void callByVal(int x) { x = x * x; } public void callByRef(ref int x) { x = x * x; } public void callByOut(out int x) { x = 3; x = x * x; }

Method arguments – call by value and by reference using System; class SquareTest { static void Main(string[] args) { Square sq = new Square(); int y = 5; int z; sq.callByVal(y); Console.WriteLine("After call by val: y = " + y); sq.callByRef(ref y); Console.WriteLine("After call by ref: y = " + y); // z uninitialized sq.callByOut(out z); Console.WriteLine("After call by z: z = " + z); }

Method arguments – call by value and by reference

When we pass objects into methods, we are passing the object reference When we pass objects into methods, we are passing the object reference  But the object reference is normally passed by value  In other words we are passing a copy of the reference into the method  The object in the calling method can still be altered in the called method  But the reference in the calling method can’t be altered – it always refers to the same object

anObject Calling method Called method Method arguments – call by value and by reference ref to anObject Copy of ref to anObject

Method arguments – call by value and by reference But we can pass a reference to a reference (!!) But we can pass a reference to a reference (!!)  Such a technique can lead to serious errors if not used wisely  The called method assumes control of the object in the calling method  However it can also be a subtle capability for experienced programmers

Method arguments – call by value and by reference anObject Calling method Called method ref to anObject ref to ref to anObject

Method arguments – call by value and by reference In this example, the called method has a reference to the reference to the object In this example, the called method has a reference to the reference to the object  In this case it could alter the original reference  For example, it could change it to reference a different object  This would then cause a memory leak which would be ultimately garbage collected

Method arguments – call by value and by reference public class myStudentRecordsApplication { public static void setIDpassByVal(StudentInfo s) { s.ID = 9999; s = new StudentInfo("no name", 0, "no fixed abode"); } public static void setIDpassByRef(ref StudentInfo s) { s.ID = 9999; s = new StudentInfo("no name", 0, "no fixed abode"); }

Method arguments – call by value and by reference class StudentInfoTest { static void Main(string[] args) { StudentInfo s=new StudentInfo("John Smith",3429, "21 Bristol Rd"); Console.Writeline(“Original object”) s.printStudentInfo(); myStudentRecordsApplication.setIDpassByVal(s); Console.Writeline(“Pass object ref by value”); s.printStudentInfo(); myStudentRecordsApplication.setIDpassByRef(ref s); Console.Writeline(“Pass object ref by reference”); s.printStudentInfo(); }

Method arguments – call by value and by reference

In the call by ref case, we have created a memory leak by altering the original reference In the call by ref case, we have created a memory leak by altering the original reference StudentInfo Calling method Called method s John Smith Bristol Rd StudentInfo no name 0 no fixed abode

Delegates and lambda expressions We often want to define a method which takes a function as an argument We often want to define a method which takes a function as an argument  For example a function tabulate(f) where f() is a function to be tabulated  We can then call tabulate(sin), tabulate(exp) etc Easy to do in C, C++ as they both have function pointers which can be assigned to any function Easy to do in C, C++ as they both have function pointers which can be assigned to any function C# and Java don’t have these C# and Java don’t have these  We can only pass objects around as arguments

Delegates and lambda expressions The solution is to create a delegate object The solution is to create a delegate object  This is an object which contains a reference to a method (function) and hence can be passed around like any other object delegate object Function to be tabulated Initialized with

Delegates and lambda expressions public delegate double tabulateDelegate(double x); class Tabulater { public void tabulate(double min, double max, double step, tabulateDelegate tabulatedFunction) { for (double x = min; x <= max; x += step) Console.Write(tabulatedFunction(x) + " "); Console.WriteLine("\n\n"); } class Program { static void Main(string[] args) { Tabulater t = new Tabulater(); // Tabulate sin(x) t.tabulate(0, Math.PI, 0.1, Math.Sin); // Tabulate exp(x) t.tabulate(-1.0, 1.0, 0.1, Math.Exp); }

Delegates and lambda expressions A lambda expression allows anonymous functions to be defined A lambda expression allows anonymous functions to be defined  Enables us, for example, to pass our own user defined functions into tabulate() A lambda expression is of the form: A lambda expression is of the form: The lambda operator => is read as ‘goes to’ The lambda operator => is read as ‘goes to’ The parameter and return types are implicit The parameter and return types are implicit Delegates can be initialized with lambda expressions Delegates can be initialized with lambda expressions (input parameter(s)) => (returned function value) eg (x) => x*x + 1 – defines f(x)=x*x + 1

Delegates and lambda expressions We can now easily tabulate our own function using a lambda expression We can now easily tabulate our own function using a lambda expression class Program { static void Main(string[] args) { Tabulater t = new Tabulater(); // Tabulate sin(x) t.tabulate(0, Math.PI, 0.1, Math.Sin); // Tabulate exp(x) t.tabulate(-1.0, 1.0, 0.1, Math.Exp); // Tabulate x*x + 1 t.tabulate(0, 2, 0.1, (x) => (x * x + 1)); }

Summary We have looked at the basis of classes and objects We have looked at the basis of classes and objects  How do declare our own classes  How to create objects of those classes We have looked at the constituents of a class We have looked at the constituents of a class  Methods  Instance fields  Properties We have looked at the idea of encapsulation as a key feature of object orientation We have looked at the idea of encapsulation as a key feature of object orientation We have looked at passing arguments by value and by reference to class methods We have looked at passing arguments by value and by reference to class methods We have looked at delegate objects and lambda expressions We have looked at delegate objects and lambda expressions