面 向 对 象 程 序 设 计 第3讲 Java程序设计基础(下) 程序的流程控制
回顾 Java 程序结构以“类”为单位。 类包括成员属性和成员方法的两方面描述。 通过封装实现对类内部数据的保护。 “包”机制能够避免命名冲突,以及保护类 内部成员。 对象初始化与构造方法的使用。 方法重载的概念。 北京科技大学天津学院-信息工程系
本讲主要内容 熟悉Java程序的组织形式 理解类、对象与成员的概念 掌握对象的创建与引用 熟悉访问修饰符和方法修饰符的使用 掌握选择、循环结构流程及其他流程控制语句 北京科技大学天津学院-信息工程系
引用与对象 MyClass mc = new MyClass( ); 这条语句实际上完成了三件事情: 1)声明引用mc,该引用的类型为MyClass,将 只能引用MyClass以及其子类的对象。 2)利用MyClass()构造方法创建MyClass对象。 3)把创建的对象赋给mc引用。 0x1001 栈内存 堆内存 this.i mc= 0x1001 null this.show() 北京科技大学天津学院-信息工程系
引用与对象——this关键字 【例2.14】不同对象对引用的赋值。 public class Reference { private String name; public Reference(String n) { name = n; } public void showName( ) { System.out.println(name); public Reference(String name) { name = name; this.name = name; public static void main(String[ ] args) { Reference r1 = new Reference("r1"); Reference r2 = new Reference("r2"); r1.showName( ); r1 = r2; } 北京科技大学天津学院-信息工程系
引用相等与对象相等的判断 【例】String对象相等的判断 public class StringEquals { public static void main(String[ ] args){ String s1 = "Hello world"; String s2 = "Hello world"; String s3 = new String("Hello world"); System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s1.equals(s3)); } 共创建了几个对象呢 内存:栈内存,堆内存,字符串常量池(堆内存中) String s1 = “Hello world”;//本语句创建了一个对象 /* 检查字符串常量池中是否已有该字符串,如果没有就创建一个字符串常量对象,然后将该字符串常量对象的地址传递给引用s1*/ String s2 = “Hello world”; //由于上一语句已经创建了对象,本语句不再重复创建相同对象 /*检查字符串常量池,发现有该字符串,则直接将已有字符串的地址传递给引用s2*/ String s3 = new String(“Hello world”); //由于s1已经创建了常量对象,本语句不再重复创建,但是new必然会创建一个新对象 /*因为字符串常量池中已经有前面创建的“Hello world”了,因此不需重复创建字符串常量对象,但是new关键字会将常量池中的串复制到堆内存中形成一个新的String类型的对象*/ 北京科技大学天津学院-信息工程系
访问修饰符 访问修饰符的作用是说明被声明的内容 (类、属性、方法)的访问权限。 通过访问修饰符把类中将被其他类调用的 内容开放出来,而把不希望别人调用的内 容隐藏起来。 4种访问修饰符: public,private,protected,无修饰符 类型 private 无修饰符 protected public 同一个类中 可访问 同一个包中的类 不可访问 不同包的子类 不同包并且非子类 //Test.java class Shape { private double perimeter; private void setPerimeter(double perimeter) { //修改为public System.out.println("计算该形状的周长"); } private void getPerimeter() { //修改为public System.out.println("输出该形状的周长"); public class Test { public static void main(String[] args) { Shape sh = new Shape(); sh.setPerimeter(3.2); sh.getPerimeter(); 北京科技大学天津学院-信息工程系
方法修饰符 方法修饰符为方法设置访问权限,包括: static final abstract 北京科技大学天津学院-信息工程系
方法修饰符 —— static 关键字static可以用于修饰变量、方法、代码 块。 //StaticDemoTest.java class StaticDemo { static int a = 23; static int b = 67; static void callme() { System.out.println("a = " + a); } public class StaticDemoTest { public static void main(String[] args) { StaticDemo.callme(); System.out.println("b = " + StaticDemo.b); //静态成员属于整个类,而不属于某一个对象 StaticDemo one = new StaticDemo(); one.a += 1; StaticDemo two = new StaticDemo(); System.out.println(“two.a = " + two.a); 北京科技大学天津学院-信息工程系
方法修饰符 —— static 【例】用static修饰变量、方法、代码块。 public class StaticSample{ static int x = 3; static int y; static void display( ){ System.out.println("x = " + x); System.out.println("y = " + y); } static{ System.out.println("static block"); y = x + 2; pubic static void main(String[] args) { StaticSample.display( ); } static block x = 3 y = 5 北京科技大学天津学院-信息工程系
方法修饰符 —— static 【例】static成员变量的初始化。 class ClassStatic { public static int i = staticInitMethod( ); public static int staticInitMethod( ){ System.out.println("static成员变量被初始化"); return 12; } pubic static void main(String[] args) { System.out.println("访问static成员变量i"); int a = ClassStatic.i; System.out.println("创建对象"); ClassStatic si = new ClassStatic( ); } 当以任何方式第一次使用某个类时,类初始化过程将会发生,这包含着static成员变量的初始化,且该过程只发生一次。 当建立对象时,该初始化过程没有重复,没有再次输出“static成员变量被初始化”。 北京科技大学天津学院-信息工程系
方法修饰符 —— final 用final修饰的类不能被继承。 用final修饰的变量,值不能被修改,即为常 量。 常量的命名规范:所有字母均大写。 北京科技大学天津学院-信息工程系
方法修饰符 —— final 【例】用final修饰常量PI,实现计算圆的面积。 public class Circle { private final double PI = 3.14; private double radius; public void setRadius(double radius) { this.radius = radius; } public double area( ){ return PI * this.radius * this.radius; 北京科技大学天津学院-信息工程系
基本数据类型 一个变量的数据类型决定了变量所能容纳的数 值和操作符。 Java是一种强类型语言,意味着每一个变量 都有一种类型且每一种类型都是经过严格定义 的。 C与Java基本数据类型的对比 北京科技大学天津学院-信息工程系
基本数据类型 北京科技大学天津学院-信息工程系 boolean只占1位。在C语言中,非0即为真: 如: while(1) { … { … if (…) break; } 在Java中,不可以用1表示true;用0表示false。 除了char型,所有类型都是signed。 C语言的char型只占1个字节,使用的是ASCII字符集(基本集128个字符->扩展集256个字符);Java语言的char型占2个字节,使用的是统一编码字符集Unicode。 Unicode被设计用来处理世界上所有的书面语言中的字符。通常用’\x0000’到’\xFFFF’之间的十六进制值来表示。 对于中文汉字来说,使用Unicode的意义是?答:一个char型变量可以存储一个汉字,但C语言不行。 演示:public class HanziUnicode { public static void main(String[] args) { char c = ‘中’; int num = c; System.out.println(num); //20013计算机转换为4E2D public class HanziUnicode { /*char c = '中'; int num = c;*/ int num1 = 0x4E2D; char s = (char)num1; System.out.println(s); 数据类型其他演示: public class TypeTest { float f; f = 1.3; System.out.println(f); } //error:possible loss of precision /*float f; f = 1.3;*/ char ch = 97; //char ch = ‘a’; System.out.println(ch); 没有初始化的变量不能使用 class VariableTest { public static void main(String [] args) { double a = 1.0; int b = 3; char c; //仅声明可以 System.out.println("双精度变量的值为: "+a); System.out.println("整型变量的值为:"+b); System.out.println(c); //没有初始化,不能使用 北京科技大学天津学院-信息工程系
数据类型转换 不同类型的数据进行混合运算时,首先需要转换为同一类型 然后运算。 自动类型转换:也称放大转换。 条件:两种类型兼容,目标类型大于源类型,布尔型与 其他类型不兼容。 强制类型转换:也称缩小转换。 条件:源类型大于其目标类型,如float值赋给int类型变 量值,此时需要显式类型转换,即 double d = 12.1 int i = (int)d; float c = 34.89675f; int b = (int) c + 10; // 将 c 转换为整型,b值为44 演示: public class Test { public static void main(String [] args) { byte b; b = 3; b = b*3; //error System.out.println("b="+b); } 提问:输出结果是?Error 因为byte类型参与运算会发生自动类型转换,相乘的结果会转换为int型。 改:b = (byte)b*3; //error,强制转换了b而已。 应改为: b = (byte)(b*3) 提问: double i; i = (float)(5/2); i = (float)5/2; 北京科技大学天津学院-信息工程系
包装类 为了能将基本类型视为对象来处理,并能连接相关的方法,Java为每个基本数据类型都提供了包装类。java.lang包中提供了每个基本数据类型对应的包装类。 基本数据类型 包装类 boolean Boolean byte Byte char Character short Short int Integer long Long float Float double Double 北京科技大学天津学院-信息工程系
包装类——例题 【例】实现基本数据类型和包装类之间的转换。 public class Convert { public static void main(String[ ] args) { int myInt = 12; Integer myInteger = new Integer (myInt); System.out.println(myInteger.intValue( )); } JDK1.5新特性:自动装箱、拆箱 北京科技大学天津学院-信息工程系
操作符 运算符 描述 示例 算术运算符 算术运算符使用数字操作数。这些运算符主要用于数学计算 +, -, *, /,% ,++, --,+= 关系运算符 关系运算符用于测试两个操作数之间的关系。使用关系运算符的表达式的结果为 boolean 型 ==, >=, <= ,!=<,> 逻辑运算符 逻辑运算符用于 boolean 操作数 &, |, ^,&&,||,! 条件运算符 条件运算符很独特,因为它是用三个操作数组成表达式的三元运算符。它可以替代某种类型的 if-else 语句 ?: 赋值运算符 赋值运算符为一个等号 =,它将值赋给变量 =, *=, /=, +=, -= public class Test { public static void main(String [] args) { int i = 3; int count = (i++)+(i++)+(i++); System.out.println(i); //6 System.out.println(count);//12 } float num = 10.0f; double num1 = 10.0; if (num == num1) { System.out.println(“num等于num1”); //显示 } else { System.out.println("num不等于num1"); int x = 85; int y = 93; if (x>=90 && y>=90) { System.out.println(“学员成绩不是A"); 北京科技大学天津学院-信息工程系
操作符优先级 【例】在复杂运算中,体现操作符的运算优先级。 public class OperatorTest { public static void main(String[ ] args) { int a = 1, b = 2, c = 3; boolean result; result = ( a == 1 ) && ( b != ++a * c ); System.out.println("the result is: " + result); } 北京科技大学天津学院-信息工程系
变量作用域 变量可以在代码块中声明,代码块用来定义作用域,代码块以左大括号开始,以右大括号结束。 class ScopeVar { public static void main(String [ ] args) { int num = 10; if ( num == 10) { int num1 = num * num; System.out.println(“num 和 num1 的值为" + num + " " + num1); } num1 = 10; System.out.println(“num 的值为" + num); //num 在内层作用域中可用 //错误!num1 未知 北京科技大学天津学院-信息工程系
小结 访问修饰符的作用。 static关键字修饰静态成员,可以直接用类名 称调用,且只能调用其它静态成员。 final关键字用来表示常量。 Java数据类型与C语言的区别,数据类型转换 及包装类的使用。 Java操作符的使用。 变量作用域的概念。 北京科技大学天津学院-信息工程系
数组的概念 数组是一个变量,用于将相同数据类型的数据 存储在存储单元中。 数组可以为多维。 一维数组由一列相同类型的数据组成,可以通过 指定数组的名称和大小来声明数组。 多维数组是数组的数组,要声明一个多维数组, 必须使用另一组方括号来指定附加索引。 北京科技大学天津学院-信息工程系
一维数组 数组的定义: int[ ] numbers; int[ ] numbers = new int[3]; 数组元素的初始化: int[ ] numbers = {1, 2, 3}; //定义时初始化 int[ ] numbers = new int[ ]{1, 2, 3};//分配空间时 初始化 numbers[0] = 1; //对某一元素赋值初始化 int[ ] numbers; numbers = {1, 2, 3}; //error int[ ] numbers = new int[3]{1, 2, 3}; //error 数组元素的访问 int[ ] numbers = new int[3]; 北京科技大学天津学院-信息工程系
二维数组 数组的定义:int[ ][ ] numbers; 数组的空间分配:numbers = new int[3][4]; 数组元素的初始化: int[][] numbers = new int[][]{{1,2,3},{4,5,6}} //ok int[][] numbers = {{1,2,3},{4,5,6}} //ok int[][] numbers = {{1,2,3},{4,5},{6}} //ok int[][] numbers = new int[][]{1,2,3,4,5,6} //error int[][] numbers = new int[2][]{{1,2,3},{4,5,6}} //error 数组元素的访问 北京科技大学天津学院-信息工程系
二维数组 Java的二维数组,每一行是一个一维数组。 在C语言中,要求每一个一维数组列数相同, 但Java允许每一行的列数不同,如: int[][] numbers; //定义 numbers = new int[3][]; //分配空间 numbers[0] = new int[5]; numbers[1] = new int[3]; numbers[2] = new int[2]; 类似C语言中的指针数组,数组中每个元素都 是引用。 北京科技大学天津学院-信息工程系
控制流语句 三种基本结构形式:顺序结构、分支结构、循 环结构。 流控制使程序员可以创建一个应用程序,该应 用程序能够检查现有的条件并决定适当的操作 过程。 循环或迭代是重要的编程结构,可用于重复执 行一组操作。 跳转语句允许以非线性的方式执行程序。 北京科技大学天津学院-信息工程系
控制流语句的类型 判断语句 循环语句 if-else 语句 switch-case 语句 while 循环 do-while 循环 for 循环 增强的for循环 北京科技大学天津学院-信息工程系
if-else 语句 if-else 语句测试条件的结果,然后根据此结 果来执行相应的操作,它可用于以两个不同的 路径来执行程序。 北京科技大学天津学院-信息工程系
if-else 语句 N Y 条件? if (condition) { action1; } if (condition1) { 语句序列 if (condition) { action1; } if (condition1) { action1; } else if (condition2) { action2; } else if (condition3) { action3; } else { action4; } if (condition) { action1; } else { action2; } N Y 条件 语句组1 语句组2 北京科技大学天津学院-信息工程系
switch-case 语句 switch-case 语句可用于替换 if-else-if 语句 switch只能测试等式,且仅适用于byte、short、int 和char类型的判断。 switch (表达式){ case 1: 操作 1 的语句; break; case 2: 操作 2 的语句; …. case n : 操作 n 的语句; default: 默认语句; } int month = 1; String name; switch (month) { case 1: name = “一月”; break; case 2: name = “二月”; …. default: name = “月份无效”; } 北京科技大学天津学院-信息工程系
循环结构——while while 只要指定的条件评估为true,while 循环则执行一个语句或一组语句。 语法 示例 int count = 0; while (count < 10) { System.out.println(count); count++; } 条件 = true while (测试) { // 语句 } 被执行 北京科技大学天津学院-信息工程系
循环结构——do-while do-while do-while循环执行某些语句,直到指定的条件为真。此循环确保循环体至少执行一次。 语法 示例 条件 = true do { System.out.println(count); count++; } while (count < 10) ; do { // 语句 }while (测试) 被执行 北京科技大学天津学院-信息工程系
循环结构——for for for循环用于按预定的次数执行语句或语句块。 语法 } 示例 条件 = true for(计数器初始化;条件判断; 增量) { 操作语句; } 计数器初始化 增量 被执行 示例 for(int count = 0; count <10; count++) { System.out.println(count); } 北京科技大学天津学院-信息工程系
循环结构——增强的for循环 主要体现在集合中,用于遍历集合中的每一项 int[ ] primes = new int[ ]{2,3,5,7,11,13,17,19}; for(int count : primes) { System.out.println(count); } 北京科技大学天津学院-信息工程系
跳转语句 两种跳转语句为: break 语句:用于终止块。 continue break 语句:用于终止块。 continue 语句:有时程序员可能希望继续循 环,而停止处理其主体内的其余代码,以进行 特定的迭代。continue 语句可用于这种操作。 北京科技大学天津学院-信息工程系
示例 打印输出下面的图形。 * * * * * * * * * * * * * * * * * * * * * * * * * public void print() { for(int i = 1; i <= this.getLines(); i++) { for(int j = 1; j <= this.getLines() - i; j++) { System.out.print(" "); } for(int j = 1; j <= i * 2 - 1; j++) { System.out.print("*"); System.out.println(); 北京科技大学天津学院-信息工程系
示例 输入一行字符,分别统计出其中英文字母、空 格、数字和其他字符的个数。 北京科技大学天津学院-信息工程系
命令行参数 main函数内为什么会有String[ ] args? Java应用程序可以从命令行接受任意数量的 参数。main方法的参数String[] args数组就 是用来保存从命令行输入的参数的。 北京科技大学天津学院-信息工程系
命令行参数 public class ComndLineArgs { public static void main(String args[ ]) { for(int i=0;i<args.length;i++) { System.out.println(args[i]); } 执行:java ComndLineArgs “Welcom to Java” to Java 执行:java ComndLineArgs “Welcom to Java” 100 56 双引号中的字符串被视为一个参数,数字则被视为字符串。 北京科技大学天津学院-信息工程系
本节小结 使用Java中的数组 掌握选择结构流程 掌握循环结构流程 掌握其他流程控制语句 北京科技大学天津学院-信息工程系
作业 实现几种排序等经典算法:冒泡法、选择法、 插入法等,并尝试测算比较不同算法的排序效 率。 课后题 北京科技大学天津学院-信息工程系