第三章 面向对象上
第三章 3.1 面向对象的概念 面向过程: 面向对象:->对现实社会的模拟 封装->隐藏实现的细节 继承->代码的重写 多态->程序的扩展 _继承 _父类引用指向子类对象 _子类重写 类与对象 Object(类) 和 对象(Class) 是面向对象方法的核心概念 类->某一类的描述,是抽象的、概念上的定义(相当于设计图) 对象->是实际存在的该类事物的个体,因而称之为实例(设计图的产品) 类的定义 类将数据和方法封装在一起,数据表示类的属性,方法表示类的行为 如: class Person{ int age;//属性 void show(){ System.out.println();//方法->行为 } } 对象的产生和使用 创建新的对象需要用new关键字来实现,对象没有被初始化之前是不能被使用得的 class TestPerson{ public static void main(String[] agrs){ Person p1=new Person(); p1.age=30; p1.show(); } } 对象变成垃圾的对象: 1、 { Person p1=new Person(); .... }//执行完大括号中的所有代码,产生的对象就会变成垃圾,因为这个对象的句柄p1已经超出作用域 2、 { Person p1=new Person(); p1=null;//在执行这句之后,虽然句柄p1没有超出作用域,但是p1不指向任何对象,垃圾 } 3、 { Person p1=new Person(); ... Person p1=p1; ... p1=null; ... }//执行完p1后,产生的Person对象不会变成垃圾,因为这个对象仍被p2引用,只有到超出p2作用域,才会成为垃圾 对象的比较 1、== 比较的是两个值得是否相同 2、equals() 比较的是两个对象的内容是否一样 如;String str1="abc"; String str2="abc"; String str3=str1; if(str1==str2){ //比较的是str1和str2这两个引用变量的值,即是内存单元 -> fasle } if(str1==str3){ //指向的是同一个内存单元 ->true } if(str1.equals(str2)){ //比较的是内存单元对应的内容 ->true } 匿名对象 创建完对象,在调用对象的方法时,也可以不定义对象的句柄,而直接调用这个对象的方法,这样的 对象叫做匿名对象。 如:Person p1=new Person(); p1.show(); -> new Person().show();//这个方法使用后,这个对象也就成了垃圾 使用匿名对象的两种方法: 1、对一个对象只需要一个的方法调用,那么久可以使用匿名对象 2、将一个匿名对象作为一个实参传递给一个函数调用 实现类的封装性 使用private 然后对外提供get和set接口... 构造函数:(constructor)用于初始化一个对象 构造函数的定义和作用 1、与类同名 2、只能被new调用 3、没有返回值 ->不同于void ,是连void都没有的 构造函数的重载: 这个其他的方法重载是一样的, 在同一个类中,方法名相同,但是参数列表不同。编译器根据参数列表的不同,调用相应的方法 构造方法的一些细节 如果程序员自己没写好构造方法,类会有一个不带参的默认构造方法。 this 引用句柄->指向当前指向的所属的对象 class person{ String name; public Person(String name){ this.name=name; } } 3.5 与来及回收油有关的知识 finalize() 方法 相当于C++中的析构方法但是这个不是你调用了就会来的! System.gc();使用这个方法可以强制启动来及回收器来回收垃圾 3.6 函数的参数传递 基本数据类型的参数传递 ->基本类型变量作为实参传递,并不能改变这个变量的值 方法的参数传递过程,并强调了方法的形式参数就相当于方法中定义的局部变量,方法调用结束时,也 就被释放了,不会影响主函数中同名的局部变量。 class PassValue{ public static void main(String[] args){ int x=5; change(x); System.out.println()x;//x=5 } public static void change(int x){ x=3; } } 引用数据类型的参数传递 对象的引用变量并不是对象本身,他们只是对象的句柄(名称),就如一个人有多个名称 java在给被调用方法的参数赋值时,值采用传值的方式,所以,基本类型数据传递的是该 数据的值本身,通过方法调用,可以改变对象的内容,但是对象的引用是不能改变的,对于数组 也属于引用类型,将数组对象作为参数传递,和下面的例子有同样的效果。 如:class PassRef{ int x; public static void main(String[] agrs){ PassRef obj=new PassRef(); obj.x=5; change(obj); System.out.println(obj.x);//-> obj.x=3 } public static void change(PassRef obj){ obj.x=3; } } 3.7 static关键字 静态变量 希望无论是否产生了对象,或产生了多少对象,某些特定的数据在内存空间只有一份。 //我们不能把任何方法体内的变量声明为静态。如:fun(){static int i=0;} 被static修饰的变量,在类被载入的时候就会被创建,类存在,static变量就会存在 静态方法:有时希望不必创建对象就可以调用某个方法,换句话说也就是该方法不用和对象 绑在一起。(用类名直接访问静态成员函数,也可以用类的实例来调用) 类的静态成员被称为类成员,对静态成员变量,我们叫做类属性,静态成员方法叫做类方法。 注意: 1、静态方法只能调用静态成员,,而不能调用非静态成员(非静态的成员需要先创建类的实例) 2、静态方法不能以任何方式引用this和super关键字 3、main()是静态的,因此JVM可以再执行main方法时不去不去创建其所在类的实例,因而在main 方法中,不能直接访问该类的非静态成员,必须创建一个实例对象后,才能去访问。 静态代码块 一个类可以使用不包含任何方法的静态代码块,当类被载入时,静态代码块被执行,且执行 一次,常用来对类属性的初始化. 单态设计模式 设计模式是在大量的实战中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式。 单态设计模式,就是采用一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例, 并且该类值提供一个取得其对象实例的方法。 如:public class TestSingle{ private static final TestSingle onlyOne=new TestSingle();//静态产生一个实例,修饰为private public static TestSingle getTestSingle(){//对外提供一个静态的获取对象的方法 return onlyOne; } private TestSingke(){//这样new操作符就不能再类外产生该类的对象了 public void show(){ System.out.println("这是一个单态设计模式..."); } } } public class Test { public static void main(String[] agrs){ TestSingle.getTestSingle().show();//获得一个TestSingle的实例 //TestSingle t=new TestSingle();//error 无法获得实例对象 } } 理解main方法的语法 由于JVM需要调用类的main方法,所以的方法的权限必须是public,又因为JVM在执行main方法时 不需要创建对象,所以方法必须是static的,该方法接受一个String类型的数组参数,该数组保存 执行java命令时传递给所运行的类的参数。 3.8 内部类 在一个类内部定义类,这就是嵌套类,内部类,内置类。 嵌套类可以访问嵌套它的类的任何成员,但是却不能被嵌套它的类访问。 类中定义的内部类 class Outer{ int outer_i=100; void test(){ Inner in=new Inner(); in.display(); } class Inner{//在Outer的范围内 void display(){//Inner 可以访问到Outer类的变量outer_i System.out.println("display: outer_i = "+outer_i); } } } class InnerClaaDemo{ public static void main(String[] agrs){ Outer outer=new Outer(); outer.test(); } } //输出结果是:diaplay: outer_i = 100 内部类保存了一个队外部类对象的引用,当内部类的成员方法访问某一变量时 ,如果该方法和内部类中都没有定义过这个变量,调用就会被传递给内部类中保存的那个 外部类对象的引用,通过那个外部类对象的引用去调用这个变量。 内部类如何被外部引用 class Outer{ private int size=10; public class Inner{//通过创建对象从外部类之外调用,要申明为public public void doStuff(){ System.out.println(++size); } } } public class TestInner{ public static void main(String[] agrs){ Outer outer=new Outer();//先创建一个外部的实例对象 outer.Inner inner=outer.new Inner();//通过外部类的实例创建内部类的实例 inner.doStuff(); } } 方法中定义的内部类 嵌套类并非只能在类里定义,也可以在几个程序块的范围内定义内部类。 如:class Outer{ int outer_i=100; void test(){ for(int i=0;i<5;i++){ class Inner{ void display(){ System.out.println("display: outer_i = "+outer_i); } } Inner inner=new Inner(); inner.display(); } } } class InnerClassDemo{ public static void main(String[] agrs){ Outer outer=new Outer(); outer.test(); } } //输出结果: display: outer_i =100 display: outer_i =100 display: outer_i =100 display: outer_i =100 display: outer_i =100 //内部类只能访问方法中的final类型的局部变量,因为final定义的局部变量是相当于一个常量 class InOut{ String str=new String("Between"); public void amethod(final int iArgs){ int it315; class Bicyle{ public void sayHello(){ System.out.println(str); System.out.println(iArgs); //System.out.println(it315);//不能访问这个变量 } } } } 3.9 使用java的文档注释