第三章 面向对象编程 讲师:复凡
学习面向对象内容的三条主线 1.Java类及类的成员 2.面向对象的三大特征 3.其它关键字
学习内容 3.1 面向对象与面向过程 3.2 java语言的基本元素:类和对象 3.3 类的成员之一:属 性 3.4 类的成员之二:方 法 3.1 面向对象与面向过程 3.2 java语言的基本元素:类和对象 3.3 类的成员之一:属 性 3.4 类的成员之二:方 法 3.5 对象的创建和使用 3.6 再谈方法 3.7 面向对象特征之一:封装和隐藏 3.8 类的成员之三:构造器(构造方法) 3.9 几个关键字:this、package、import
3.1 面向对象与面向过程 面向对象(OOP)与面向过程 面向对象的三大特征 二者都是一种思想,面向对象是相对于面向过程而言的。面向过程,强调的是功能行为。面向对象,将功能封装进对象,强调具备了功能的对象。 面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如抽象、分类、继承、聚合、多态等。 面向对象的三大特征 封装 (Encapsulation) 继承 (Inheritance) 多态 (Polymorphism) OOP: Object Oriented Programming 面向过程:procedure oriented programming
例子:人把大象装冰箱 人 冰箱 大象 1.打开冰箱 人{ 打开(冰箱){ 冰箱.开门(); } 操作(大象){ 大象.进入(); 关闭(冰箱){ 冰箱.关门(); 冰箱{ 开门(){} 关门(){} 2.把大象装进冰箱 3.把冰箱门关住 大象{ 进入(){ } } 面向过程 面向对象
类与类之间的关系 关联关系 继承关系
类与类之间的关系 聚 集 组 合 聚合关系
面向对象的思想概述 程序员从执行者转化成了指挥者。 完成需求时: 类(class)和对象(object)是面向对象的核心概念。 先去找具有所需功能的对象来用。 如果该对象不存在,那么创建一个具有所需功能的对象。 这样简化开发并提高复用。 类(class)和对象(object)是面向对象的核心概念。 类是对一类事物描述,是抽象的、概念上的定义 对象是实际存在的该类事物的每个个体,因而也称实例(instance)。 “万事万物皆对象”
生活中描述事物无非就是描述事物的属性和行为。如:人有身高,体重等属性,有说话,打球等行为。 Java类及类的成员 现实世界万事万物是由分子、原子构成的。同理,Java代码世界是由诸多个不同功能的类构成的。 现实世界中的分子、原子又是由什么构成的呢?原子核、电子!那么,Java中用类class来描述事物也是如此 属 性:对应类中的成员变量 行 为:对应类中的成员方法 生活中描述事物无非就是描述事物的属性和行为。如:人有身高,体重等属性,有说话,打球等行为。 Field = 属性 = 成员变量,Method = (成员)方法 = 函数
面向对象的思想概述 可以理解为:类 = 汽车设计图;对象 = 实实在在的汽车 面向对象程序设计的重点是类的设计 定义类其实是定义类中的成员(成员变量和成员方法)
1.java类及类的成员 类的成员构成 version 1.0
类的成员构成 verson 2.0
类的语法格式 修饰符 class 类名 { 属性声明; 方法声明; } 说明:修饰符public:类可以被任意访问 类的正文要用{ }括起来 类的正文要用{ }括起来 举例: public class Person{ private int age ; //声明私有变量 age public void showAge(int i) { //声明方法showAge( ) age = i;
创建Java自定义类 步骤: 定义类(考虑修饰符、类名) 编写类的属性(考虑修饰符、属性类型、属性名、初始化值) 编写类的方法(考虑修饰符、返回值类型、方法名、形参等) 练习: 定义Person、Animal、ClassRoom、Zoo等类,加以体会。
3.3 类的成员之一:属性 语法格式: 修饰符 类型 属性名 =初值 ; 说明:修饰符private:该属性只能由该类的方法访问。 修饰符 类型 属性名 =初值 ; 说明:修饰符private:该属性只能由该类的方法访问。 修饰符public:该属性可以被该类以外的方法访问。 类型:任何基本类型,如int、boolean或任何类。 举例: public class Person{ private int age; //声明private变量 age public String name = “Lila”; //声明public变量 name }
变量的分类:成员变量与局部变量 在方法体外,类体内声明的变量称为成员变量。 在方法体内部声明的变量称为局部变量。 所有 注意:二者在初始化值方面的异同: 同:都有生命周期 异:局部变量除形参外,需显式初始化。 实例变量(不以static修饰) 成员变量 所有 变量 类变量(以static修饰) 形参(方法签名中定义的变量) 局部变量 方法局部变量(在方法内定义) 代码块局部变量(在代码块内定义)
成员变量(属性)和局部变量的区别? 成员变量: 局部变量: 成员变量定义在类中,在整个类中都可以被访问。 成员变量分为类成员变量和实例成员变量,实例变量存在于对象所在的堆内存中。 成员变量有默认初始化值。 成员变量的权限修饰符可以根据需要,选择任意一个 局部变量: 局部变量只定义在局部范围内,如:方法内,代码块内等。 局部变量存在于栈内存中。 作用的范围结束,变量空间会自动释放。 局部变量没有默认初始化值,每次必须显式初始化。 局部变量声明时不指定权限修饰符
3.4 类的成员之二:方 法 private int age; 3.4 类的成员之二:方 法 语法格式: 修饰符 返回值类型 方法名 ( 参数列表) { 方法体语句; } 说明: 修饰符:public, private, protected等。 返回值类型:return语句传递返回值。没有返回值:void。 举例: public class Person{ private int age; public int getAge() { return age; } //声明方法getAge public void setAge(int i) { //声明方法setAge age = i; //将参数i的值赋给类的成员变量age
3.5 对象的创建和使用 Java类及类的成员 如何使用java类? Java类的实例化,即创建类的对象
对象的创建和使用 使用new +构造器创建一个新的对象; 使用“对象名.对象成员”的方式访问对象成员(包括属性和方法); 举例: public class Zoo{ public static void main(String args[]){ Animal xb=new Animal(); xb.legs=4; System.out.println(xb.legs); xb.eat(); xb.move(); } public class Animal { public int legs; public void eat(){ System.out.println(“Eating.”); } public viod move(){ System.out.println(“Move.”);
对象的创建和使用 如果创建了一个类的多个对象,对于类中定义的属性,每个对象都拥有各自的一套副本,且互不干扰。 举例: public class Zoo{ public static void main(String args[]){ Animal xb=new Animal(); Animal xh=new Animal(); xb.legs=4; xh.legs=0; System.out.println(xb.legs); //4 System.out.println(xh.legs); //0 xb.legs=2; System.out.println(xb.legs); //2 } } 如果创建了一个类的多个对象,对于类中定义的属性,每个对象都拥有各自的一套副本,且互不干扰。
练 习 1 编写教师类和学生类,并通过测试类创建对象进行测试 学生类 属性: 姓名 年龄 参加的课程 兴趣 方法: 显示学生的个人信息 练 习 1 编写教师类和学生类,并通过测试类创建对象进行测试 学生类 属性: 姓名 年龄 参加的课程 兴趣 方法: 显示学生的个人信息 教师类 属性: 姓名 专业 教授的课程 教龄 方法: 显示教师的个人信息
匿名对象 我们也可以不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象。 使用情况 如:new Person().shout(); 使用情况 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。 我们经常将匿名对象作为实参传递给一个方法调用。
练习2 Person name:String age:int 1.创建一个Person类,其定义如下: sex:int 要求:(1)创建Person类的对象,设置该对象的name、age和sex属性,调用study方法,输出字符串“studying”,调用showAge()方法显示age值,调用addAge()方法给对象的age属性值增加2岁。 (2)创建第二个对象,执行上述操作,体会同一个类的不同对象之间的关系。 Person name:String age:int sex:int +study():void +showAge():void +addAge(int i):int 2.利用面向对象的编程方法,设计类Circle计算圆的面积。
3.6 方法(method) 什么是方法(函数)? 方法是类或对象行为特征的抽象,也称为函数。 Java里的方法不能独立存在,所有的方法必须定义在类里。 修饰符 返回值类型 方法名(参数类型 形参1,参数类型 形参2,….){ 程序代码 return 返回值; } 其中: 形式参数:在方法被调用时用于接收外部传入的数据的变量。 参数类型:就是该形式参数的数据类型。 返回值:方法在执行完毕后返还给调用它的程序的数据。 返回值类型:方法要返回的结果的数据类型。 实参:调用方法时实际传给函数形式参数的数据。 如何理解方法返回值类型为void的情况 ?
方法的调用 注 意: 没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。 注 意: 没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。 定义方法时,方法的结果应该返回给调用者,交由调用者处理。 方法中只能调用方法,不可以在方法内部定义方法。
方法的重载(overload) 重载的概念 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。 重载的特点: 与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。 重载示例: //返回两个整数的和 int add(int x,int y){return x+y;} //返回三个整数的和 int add(int x,int y,int z){return x+y+z;} //返回两个小数的和 double add(double x,double y){return x+y;}
函数的重载 public class PrintStream{ public static void print(int i) {……} public static void print(float f) {……} private static void print(String s) {……} public static void main(String[] args){ print(3); print(1.2f); print(“hello!”); }
练习3 1.判 断: 与void show(int a,char b,double c){}构成重载的有: void show(int x,char y,double z){} //no int show(int a,double c,char b){} //yes c) void show(int a,double c,char b){} //yes d) boolean show(int c,char b){} //yes e) void show(double c){} //yes f) double show(int x,char y,double z){} //no g) void shows(){double c} //no
练习4 2.编写程序,定义三个重载方法并调用。方法名为mOL。 三个方法分别接收一个int参数、两个int参数、一个字符串参数。分别执行平方运算并输出结果,相乘并输出结果,输出字符串信息。 在主类的main ()方法中分别用参数区别调用三个方法。 3.定义三个重载方法max(),第一个方法求两个int值中的最大值,第二个方法求两个double值中的最大值,第三个方法求三个double值中的最大值,并分别调用三个方法。
可变参数 public static void test(int a ,String[] books); //下面采用数组形参来定义方法 public static void test(int a ,String[] books); //以可变个数形参来定义方法 public static void test(int a ,String…books); 说明: 1.可变参数:方法参数部分指定类型的参数个数是可变多个 2.声明方式:方法名(参数的类型名...参数名) 3.可变参数方法的使用与方法参数部分使用数组是一致的 4.方法的参数部分有可变形参,需要放在形参声明的最后
可变参数 public void test(String[] msg){ System.out.println(“含字符串数组参数的test方法 "); } public void test1(String book){ System.out.println(“****与可变形参方法构成重载的test1方法****"); public void test1(String ... books){ System.out.println("****形参长度可变的test1方法****"); public static void main(String[] args){ TestOverload to = new TestOverload(); //下面两次调用将执行第二个test方法 to.test1(); to.test1("aa" , "bb"); //下面将执行第一个test方法 to.test(new String[]{"aa"});
方法的参数传递 方法,必须有其所在类或对象调用才有意义。若方法含有参数: 形参:方法声明时的参数 实参:方法调用时实际传给形参的参数值 Java的实参值如何传入方法呢? Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。
方法的参数传递 public class TestTransfer { public static void swap(int a , int b){ int tmp = a; a = b; b = tmp; System.out.println("swap方法里,a的值是" + a + ";b的值是" + b); } public static void main(String[] args) { int a = 6; int b = 9; swap(a , b); System.out.println("交换结束后,变量a的值是" + a + ";变量b的值是" + b); } }
方法的参数传递 class DataSwap{ public int a; public int b; } public class TestTransfer1 { public static void swap(DataSwap ds){ int tmp = ds.a; ds.a = ds.b; ds.b = tmp; System.out.println("swap方法里,a Field的值是" + ds.a + ";b Field的值是" + ds.b); public static void main(String[] args) { DataSwap ds = new DataSwap(); ds.a = 6; ds.b = 9; swap(ds); System.out.println("交换结束后,a Field的值是"
class Value { int i = 15; } class Test { public static void main(String argv[]) { Test t = new Test(); t.first(); public void first() { int i = 5; Value v = new Value(); v.i = 25; second(v, i); System.out.println(v.i); public void second(Value v, int i) { i = 0; v.i = 20; Value val = new Value(); v = val; System.out.println(v.i + " " + i); }
3.7 面向对象特征之一:封装和隐藏 使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。 3.7 面向对象特征之一:封装和隐藏 使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。 public class Animal { public int legs; public void eat(){ System.out.println(“Eating.”); } public void move(){ System.out.println(“Moving.”); public class Zoo{ public static void main(String args[]){ Animal xb=new Animal(); xb.legs=4; System.out.println(xb.legs); xb.eat();xb.move(); } }
信息的封装和隐藏 Java中通过将数据声明为私有的(private),再提供公共的(public)方法:getXxx()和setXxx()实现对该属性的操作,以实现下述目的: 隐藏一个类中不需要对外提供的实现细节; 使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作; 便于修改,增强代码的可维护性;
信息的封装和隐藏 public class Animal{ private int legs;//将属性legs定义为private,只能被Animal类内部访问 public void setLegs(int i){ //在这里定义方法 eat() 和 move() if (i != 0 && i != 2 && i != 4){ System.out.println("Wrong number of legs!"); return; } legs=i; public int getLegs(){ return legs; } } public class Zoo{ public static void main(String args[]){ Animal xb=new Animal(); xb.setLegs(4); //xb.setLegs(-1000); xb.legs=-1000; //非法 System.out.println(xb.getLegs());
四种访问权限修饰符 Java权限修饰符public、protected、private置于类的成员定义前,用来限定对象对该类成员的访问权限。 类内部 同一个包 子类 任何地方 private Yes (缺省) protected public 对于class的权限修饰只可以用public和default(缺省)。 public类可以在任意地方被访问。 default类只可以被同一个包内部的类访问。
public protected default private
练习4 1.创建程序,在其中定义两个类:Person和TestPerson类。定义如下: 用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。在TestPerson类中实例化Person类的对象b,调用setAge()和getAge()方法,体会Java的封装性。 Person -age:int +setAge(i: int) +getAge(): int
3.8 类的成员之三:构造器(构造方法) 构造器的特征 它具有与类相同的名称 它不声明返回值类型。(与声明为void不同) 3.8 类的成员之三:构造器(构造方法) 构造器的特征 它具有与类相同的名称 它不声明返回值类型。(与声明为void不同) 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值 构造器的作用:创建对象;给对象进行初始化 如:Order o = new Order(); Person p = new Person(Peter,15); 如同我们规定每个“人”一出生就必须先洗澡,我们就可以在“人”的构造方法中加入完成“洗澡”的程序代码,于是每个“人”一出生就会自动完成“洗澡”,程序就不必再在每个人刚出生时一个一个地告诉他们要“洗澡”了。
构造器 语法格式: 修饰符 类名 (参数列表) { 初始化语句; } 举 例: 修饰符 类名 (参数列表) { 初始化语句; } 举 例: public class Animal { private int legs; public Animal() {legs = 4; } //构造器 public void setLegs(int i) { legs = i; } public int getLegs(){return legs;} 创建Animal类的实例:Animal a=new Animal(); //调用构造器,将legs初始化为4。
构造器 根据参数不同,构造器可以分为如下两类: 隐式无参构造器(系统默认提供) 显式定义一个或多个构造器(无参、有参) 注 意: 注 意: Java语言中,每个类都至少有一个构造器 默认构造器的修饰符与所属类的修饰符一致 一旦显式定义了构造器,则系统不再提供默认构造器 一个类可以创建多个重载的构造器 父类的构造器不可被子类继承
练习5 1. 在前面定义的Person类中添加构造器,利用构造器设置所有人的age属性初始值都为18。 2. 修改上题中类和构造器,增加name属性,使得每次创建Person对象的同时初始化对象的age属性值和name属性值。 Person -name:String +setName(i: String) +getName(): String
练习5 3.定义一个“点”(Point)类用来表示三维空间中的点(有三个坐标)。要求如下: 1)可以生成具有特定坐标的点对象。 2)提供可以设置三个坐标的方法。 3)提供可以计算该“点”距原点距离平方的方法。 4.编写两个类,TriAngle和TestTriAngle,其中TriAngle中声明私有的底边长base和高height,同时声明公共方法访问私有变量;另一个类中使用这些公共方法,计算三角形的面积。
构造器重载 构造器一般用来创建对象的同时初始化对象。如 class Person{ String name; int age; public Person(String n , int a){ name=n; age=a;} } 构造器重载使得对象的创建更加灵活,方便创建各种不同的对象。 构造器重载举例: public class Person{ public Person(String name, int age, Date d) {this(name,age);…} public Person(String name, int age) {…} public Person(String name, Date d) {…} public Person(){…} 构造器重载,参数列表必须不同
构造器重载举例 public class Person { private String name; private int age; private Date birthDate; public Person(String name, int age, Date d) { this.name = name; this.age = age; this.birthDate = d; } public Person(String name, int age) { this(name, age, null); //this.name=name; this.age=age; this.birthDate=null; public Person(String name, Date d) { this(name, 30, d); //this.name=name; this.age=30; this.birthDate=d; public Person(String name) { this(name, 30); //this.name=name; this.age=30;
练习6 (1)定义Person类,有4个属性:String name; int age; String school; String major (2)定义Person类的3个构造方法: 第一个构造方法Person(String n, int a)设置类的name和age属性; 第二个构造方法Person(String n, int a, String s)设置类的name, age 和school属性; 第三个构造方法Person(String n, int a, String s, String m)设置类的name, age ,school和major属性; (3)在main方法中分别调用不同的构造方法创建的对象,并输出其属性值。
3.9 关键字—this 在java中,this关键字比较难理解,它的作用和其词义很接近。 它在方法内部使用,即这个方法所属对象的引用; 它在构造器内部使用,表示该构造器正在初始化的对象。 this表示当前对象,可以调用类的属性、方法和构 造器 什么时候使用this关键字呢? 当在方法内需要用到调用该方法的对象时,就用this。
使用this,调用属性、方法 class Person{ // 定义Person类 private String name ; private int age ; public Person(String name,int age){ this.name = name ; this.age = age ; } public void getInfo(){ System.out.println("姓名:" + name) ; this.speak(); } public void speak(){ System.out.println(“年龄:” + this.age);
使用this调用本类的构造器 3.this可以作为一个类中,构造器相互调用的特殊格式 class Person{ // 定义Person类 private String name ; private int age ; public Person(){ // 无参构造 System.out.println("新对象实例化") ; } public Person(String name){ this(); // 调用本类中的无参构造方法 this.name = name ; public Person(String name,int age){ this(name) ; // 调用有一个参数的构造方法 this.age = age; public String getInfo(){ return "姓名:" + name + ",年龄:" + age ; } }
注意: 1.使用this()必须放在构造器的首行! 2.使用this调用本类中其他的构造器,保证至少有一个构造器是不用this的。
练习7 添加必要的构造器,综合应用构造器的重载,this关键字。 Girl Boy -name:String -name:String +setName(i: String) +getName(): String +marry(boy:Boy) Boy -name:String -age:int +setName(i: String) +getName(): String +setAge(i: int) +getAge(): int +marry(girl:Girl) +shout():void
JavaBean JavaBean是一种Java语言写成的可重用组件。 所谓JavaBean,是指符合如下标准的Java类: 类是公共的 有一个无参的公共的构造器 有属性,且有对应的get、set方法 用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。
JavaBean示例 public class TestJavaBean{ private String name; //属性一般定义为private private int age; public TestJavaBean(){} public int getAge(){ return age; } public void setAge(int age){ this.age = age; public String getName(){ return name; public void setName(String name){ this.name = name;
0512-57882866 www.bcdaren.com 昆山爱达人 1250121864 昆山爱达人信息技术有限公司 视频录制: 视频提供 视频录制: 联系电话: 0512-57882866 官网地址: www.bcdaren.com 联系公众号: 昆山爱达人 联系QQ: 1250121864 编程达人APP: