1、JavaSE1面向对象1基础1、课程名称:面向对象(基础)2、知识点2.1、上次课程的主要知识点1、 两个环境变量 PATH:设置JDK的操作指令的环境 CLASSPATH:设置类的路径, java执行的时候要找到classpath,之后找到对应的class文件2、 Java的数据类型: 基本数据类型: |- 数值型: |- 整数:byte、short、int、long |- 浮点型:float、double |- 字符型:char |- boolean型:boolean 引用数据类型:数组、类、接口 一个整数的默认类型是int,一个小数的默认类型是double3、 关键字的 未使用到的关键字
2、:const、goto JDK 1.4增加的关键字:assert JDK 1.5增加的关键字:enum4、 方法的概念 方法就是可重复调用的一段代码段 方法的声明格式,(当前讲可以由主方法直接调用):public static 返回值类型 方法名称(参数列表) 返回值类型:可以是任意的数据类型,包括基本和引用 递归调用:自己调用自己,但是必须有结束条件5、 数组 数组就是一组相关变量的集合,通过下标访问数组 数组的定义格式: |- 动态初始化:数据类型 数组名称 = new 数据类型长度 ; |- 静态初始化:数据类型 数组名称 = 值, 值, 值, 值, 值 ; 数组本身属于引用数据类型,所
3、以需要进行栈和堆的划分,之前也简单的演示了的栈-堆的分配问题。 Java中提供了System.arraycopy()完成数组复制,和java.util.Arrays.sort()完成数组排序2.2、本次预计讲解的知识点1、 介绍面向对象的基本概念2、 类与对象的关系3、 对象的引用传递及内存分配问题4、 类的封装性5、 构造方法和匿名对象6、 建立类的开发思路7、 String类的特点及操作方法3、具体内容3.1、面向对象 此概念如果直接去解释的话可能会比较抽象,因为大家缺少对原始的面向过程的开发语言的了解。 面向过程是很难适应变化的,而面向对象因为有其完整的分析思路,所以可以任意的进行修改。
4、 面向对象从概念上讲分为以下三种:OOA、OOD、OOP |- OOA:面向对象分析(Object Oriented Analysis) |- OOD:面向对象设计(Object Oriented Design) |- OOP:面向对象程序(Object Oriented Programming) 但是,我们在学习中并不会严格的按照以上的步骤走,我们的分析和解决问题的思路来源于现实生活。 面向对象中有三大特征: 封装性:所有的内容对外部不可见 继承性:将其他的功能继承下来继续发展 多态性:方法的重载本身就是一个多态性的体现3.2、类与对象3.2.1、两者的关系 在面向对象的概念中类和对象是一个
5、绝对的重点问题,下面就要分析类和对象的关系。 类表示一个共性的产物,是一个综合的特征,而对象,是一个个性的产物,是一个个体的特征。 类必须通过对象才可以使用,那么对象的所有操作都在类中定义。 类由属性和方法组成: 属性:就相当于一个个的特征 方法:就相当于人的一个个的行为,例如:说话、吃饭、唱歌、睡觉3.2.2、类的定义格式 在Java中可以使用以下的语句定义一个类:class 类名称 属性名称 方法名称() 但是,在定义类的时候类中的方法声明时,可以暂时不加入public static,而只写返回值类型和方法名称。下面按照以上的格式定义出一个Person类class Person Strin
6、g name ; / 表示姓名 int age ; / 表示年龄 void tell() System.out.println(姓名: + name + ;年龄: + age) ; ; 以上定义出了一个类,但是这个类要想被使用,则必须依靠对象。3.2.3、对象的定义格式 一个类要想真正的进行操作,则必须依靠对象,对象的定义格式如下:类名称 对象名称 = new 类名称() ; 按照以上的格式就可以产生对象了。 如果要想访问类中的属性或方法,则可以依靠以下的语法形式:访问类中的属性:对象.属性 ;调用类中的方法:对象.方法() ;范例:调用Person类中的属性和方法class Person S
7、tring name ; / 表示姓名 int age ; / 表示年龄 void tell() System.out.println(姓名: + name + ;年龄: + age) ; ;public class OODemo02 public static void main(String args) Person per = new Person() ; / 声明对象并实例化 per.name = 张三 ; / 设置per对象的name属性内容 per.age = 30 ; / 设置per对象的age属性内容 per.tell() ; / 调用类中的方法 ; 此时,所有的操作已经正常的
8、调用完成,而且一个类可以使用了,但是以上的操作有以下几点必须说明。 在java中对象声明有两种含义 |- 声明对象:Person per = null ; / 表示声明了一个对象,但是此对象无法使用,per没有具体的内存指向 |- 实例化对象:per = new Person() ; / 表示实例化了对象,可以使用public class OODemo03 public static void main(String args) Person per = null ; / 声明对象 per = new Person() ; / 实例化对象 per.name = 张三 ; / 设置per对象的n
9、ame属性内容 per.age = 30 ; / 设置per对象的age属性内容 per.tell() ; / 调用类中的方法 ; 对象属于引用数据类型,所以也需要进行内存的划分。 |- 不管任何情况下,只要是调用了关键字new,则表示开辟新的堆内存空间 所以在使用类的时候必须考虑到堆-栈的引用空间,但是在这里有一个需要说明的问题: 如果一个类中没有使用关键字new进行内存的开辟,则将出现以下的问题:Exception in thread main java.lang.NullPointerException at OODemo03.main(OODemo03.java:12) 出现了“空指向
10、”问题,那么此问题将陪伴大家的开发人生。造成此类问题的根源非常简单,因为没有开辟对应的堆内存空间,所以出现以上的错误。 那么,如果现在产生多个对象呢?这些对象之间会不会互相影响呢?public class OODemo04 public static void main(String args) Person per1 = null ; / 声明对象 Person per2 = null ; / 声明对象 per1 = new Person() ; / 实例化对象 per2 = new Person() ; / 实例化对象 per1.name = 张三 ; / 设置per对象的name属性内容
11、 per1.age = 30 ; / 设置per对象的age属性内容 per2.name = 李四 ; per2.age = 33 ; per1.tell() ; per2.tell() ; / 调用类中的方法 ; 以上的程序,可以得出以下的内存关系图提问:在类的操作中,所有的对象名称放在栈内存中,所有的对象的具体内容放在堆内存之中,那么类中的方法放在那里了? 实际上所有的方法放在了全局代码区中。 那么,对象间既然属于引用数据类型的操作,所以肯定也是可以进行引用传递的,如果要想进行引用传递,就是将一个堆内存的空间地址的使用权给了其他对象。class Person String name ; /
12、 表示姓名 int age ; / 表示年龄 void tell() System.out.println(姓名: + name + ;年龄: + age) ; ;public class OODemo05 public static void main(String args) Person per1 = null ; / 声明对象 Person per2 = null ; / 声明对象 per1 = new Person() ; / 实例化对象 per1.name = 张三 ; / 设置per对象的name属性内容 per1.age = 30 ; / 设置per对象的age属性内容 per
13、2 = per1 ; 将per1对象的堆内存空间给了per2,那么此时的内存关系图 per2.name = 李四 ; per1.tell() ; per2.tell() ; / 调用类中的方法 ; 继续观察以下的一种情况:class Person String name ; / 表示姓名 int age ; / 表示年龄 void tell() System.out.println(姓名: + name + ;年龄: + age) ; ;public class OODemo05 public static void main(String args) Person per1 = null ;
14、 / 声明对象 Person per2 = null ; / 声明对象 per1 = new Person() ; / 实例化对象 per2 = new Person() ; / 实例化对象 per2.name = 王五 ; per1.name = 张三 ; / 设置per对象的name属性内容 per1.age = 30 ; / 设置per对象的age属性内容 per2 = per1 ; per2.name = 李四 ; per1.tell() ; per2.tell() ; / 调用类中的方法 ; 从本道程序之中,可以清楚的发现垃圾对象的产生,垃圾对象将被系统通过GC进行自动的垃圾回收,并
15、释放掉内存空间。3.3、封装性(重点) 在讲解封装性之前,来看一下以下的代码:class Person String name ; / 表示姓名 int age ; / 表示年龄 void tell() System.out.println(姓名: + name + ;年龄: + age) ; ;public class OODemo07 public static void main(String args) Person per = new Person() ; per.name = 张三 ; per.age = -30 ; per.tell() ; ; 以上的操作代码并没有出现了语法错误
16、,但是出现了逻辑错误。那么此时,这种操作并不是很合乎正常的逻辑。 造成此类问题的根源在与,可以通过对象直接访问类中的属性。那么,此时就需要对类中的内容进行封装,使用private关键字,使用之后的效果如下:class Person private String name ; / 表示姓名 private int age ; / 表示年龄 void tell() System.out.println(姓名: + name + ;年龄: + age) ; ;public class OODemo08 public static void main(String args) Person per =
17、 new Person() ; per.name = 张三 ; per.age = -30 ; per.tell() ; ;编译时出现了以下的错误提示:OODemo08.java:11: name has private access in Person per.name = 张三 ; OODemo08.java:12: age has private access in Person per.age = -30 ; 2 errors name和age属性是私有的访问权限,不能被外部所访问,那么此时,既然不能被外部所访问,则肯定是安全的了。 所以,在Java开发中对于所有的私有属性要想进行访问
18、,必须通过setter和getter方法,这是一个标准的操作,例如: 现在有String name属性 setter:public void setName(String str) getter:public String getName()class Person private String name ; / 表示姓名 private int age ; / 表示年龄 void tell() System.out.println(姓名: + getName() + ;年龄: + getAge() ; public void setName(String str) name = str ;
19、public void setAge(int a) age = a ; public String getName() return name ; public int getAge() return age ; ;public class OODemo09 public static void main(String args) Person per = new Person() ; per.setName(张三) ; per.setAge(-30) ; per.tell() ; ; 但是,以上的操作中仍然没有解决年龄是负数的情况。需要在setter方法上加上检测措施,而在getter方法上
20、只是简单的把内容返回即可。class Person private String name ; / 表示姓名 private int age ; / 表示年龄 void tell() System.out.println(姓名: + getName() + ;年龄: + getAge() ; public void setName(String str) name = str ; public void setAge(int a) if(a0&a0&a0&a0&a150) age = a ; public String getName() return name ; public int ge
21、tAge() return age ; ;public class OODemo12 public static void main(String args) Person per = null ; per = new Person(张三,30) ; per.tell() ; ; 但是,以上的操作方法中,属性的内容可以直接通过构造进行设置,所以,即使设置了错误的内容,也依然可以为属性赋值,那么此时最好的做法是,在构造方法中同样调用检查的操作。 public Person(String n,int a) / 构造方法 setName(n) ; / 设置name属性 setAge(a) ; / 设
22、置age属性 另外,要提醒的是,如果现在需要明确的表示出一个方法是本类中定义的方法也可以加上this.的形式,例如: public Person(String n,int a) / 构造方法 this.setName(n) ; / 设置name属性 this.setAge(a) ; / 设置age属性 那么在类中构造方法本身也是可以进行重载的,只要参数的类型或个数不同,那么就可以完成构造方法的重载。class Person private String name ; / 表示姓名 private int age ; / 表示年龄 public Person() public Person(String n) this.setName(n) ; public Person(String n,int a) / 构造方法 this.setName(n) ; / 设置name属性 this.setAge(a) ; / 设置age属性 void tell() System.out.println(姓名: + getName() + ;年龄: + getAge() ; public void setName(String str) name = str ;