黑马程序员 面对对象(二)

来源:互联网 发布:数空车床编程视频教程 编辑:程序博客网 时间:2024/06/12 22:18

-----------android培训java培训、java学习型技术博客、期待与您交流! ------------

类与类之间的关系:继承,聚集。

对于多个类中共有的属性方法,则可以提取出来,定义成一个父类。
一个类继承另一个类,这个类就有了被继承类定义的属性,方法。
继承的好处:
1,提高了代码的复用性。
2,让类与类之间产生关系,从何实现多态的特性。
java中不支持多继承,只支持单继承。但支持对接口的多实现。接口对接口的多继承,

聚集关系:
聚合关系:如鼓手是乐队里的一部分。
组合关系:如手是身体的一部分。

变量
如果子类出现非私有的同名变量时,子类要访问本类中的变量,用this。
子类要访问父类中的同名变量,用super。
super的使用和this的使用几乎一致,代表的是父类对象的引用。
当函数前面没有public,private定义权限时,系统默认权限(default)。此权限介于public private之间。


函数的覆盖:见第一篇的重载和覆盖的区别。


构造函数
因为覆盖的条件,构造函数不可能存在覆盖。
加载子类文件的时候会先加载父类文件。因为在对子类的构造函数默认第一行有一条隐式的语句super();
super()会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();
super()和this();只能出现一个。
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要知道父类是如何对这些数据进行初始化。
子类一定要访问父类中的构造函数。如果父类中没有空构造函数,或者要访问父类中指定的构造函数,则子类需手动定义super或者this语句来指定要访问的构造函数。
class ExtendsDemo {public static void main(String[] args) {Zi z = new Zi();Zi z1 = new Zi(1);}}class Fu{Fu(){System.out.println("我是父类");}Fu(int x){System.out.println("我也是父类");}}class Zi extends Fu{Zi(){//super();System.out.println("我是子类");}Zi(int x){//super();System.out.println("我也是子类");}}

运行结果: 

我是父类我是子类我是父类我也是子类
class Fu{int i;public Fu(String s){i =1;}public void print(){System.out.println("fu");}}public class Zi extends Fu {public Zi(String s){super(s);//不写这句话会编译失败。i =2;}public static void main(String[] args){Zi zi = new Zi("a");System.out.println(zi.i);}}
关键字final:
1,可以修饰类,函数,变量。
2,被final修饰的类不可以被继承。
被final修饰的方法不可以被复写。
被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量。(当一些数据是固定的,可以加上final修饰。为了增强阅读性,可以给该数字起个名字。字母全部大写,多个单词直接用_链接。)
3,内部类定义在类中的局部位置上,只能访问该局部被final修饰的局部变量。
当定义一个类,不希望被继承的时候,可以将类用final修饰。如String类

抽象类:当多个类中有相同功能,但是功能主题不同,可以将次功能定义抽取出来,不抽取功能主体。
1,抽象方法一定在抽象类中。
2,抽象方法和抽象类必须被abstract关键字修饰。
3,抽象类无法创建对象。调用抽象方法没意义。
4,抽象类中的方法要被调用,必须由子类复写起所有的抽象方法后,建立子类对象调用。否则其子类也是个抽象类。
好处:强制子类实现其抽象功能。

模版方法模式:
在定义功能时,功能的一部分是确定的,一部分不确定。确定的部分使用不确定
部分,则可以把不确定部分暴露出去,让子类去实现。
class Stencil {public static void main(String[] args) {new SubGetTime().getTime();}}abstract class GetTime{public final void getTime(){long start = System.currentTimeMillis();runCode();long end = System.currentTimeMillis();System.out.println("运行时间:"+(end-start)+"毫秒");}public abstract void runCode();}class SubGetTime extends GetTime{public void runCode(){for (int x=0;x<4000 ;x++ ){System.out.print(x);}}}

接口:interface,接口是对外暴露的规则。对程序进行功能扩展。
接口特点:
1,接口常见定义:常量,抽象方法。
2,接口中的成员都有固定修饰符。
常量:public static final
方法:public abstract
接口中的成员都是public的,方法都是abstract
接口用来实现,用implements关键字。接口可以被类多实现。
类之间只有单继承,但接口之间有多继承。

多态:事物存在的多种体现形态。
1,多态的体现:
父类引用指向子类对象。父类的引用也可以接受自己的子类对象。
2,多态的前提
类与类之间存在关系,继承或者实现。
3,多态的好处与弊端
好处是提高了程序的扩展性,弊端是只能使用父类的引用访问父类中的成员。
还有就是通常存在方法的覆盖。
父类引用指向子类对象,如果调用的方法父类中没有。则编译失败。
当父类中有该非静态方法,运行时调用的是子类覆盖后的方法。

注意:

1,多态中,对于成员变量和静态成员函数,无论编译和运行,都参考引用变量所属的类。
2,父类引用指向子类对象时,子类对象类型被提升。如果想使用子类的特有方法,可以强制将父类的引用,转成子类类型。
abstract class Student{public abstract void study();public void sleep(){System.out.println("躺着睡");}}class BaseStudent extends Student{//实现study方法public void study(){System.out.println("base study");}//覆盖sleep()方法public void sleep(){System.out.println("坐着睡");}public void play(){System.out.println("玩游戏");} }class AdvStudent extends Student{public void study(){System.out.println("adv study");}}class DoStudent{public void doSth(Student stu){stu.study();stu.sleep();}}class  DuoTaiDemo{public static void main(String[] args) {DoStudent ds = new DoStudent();ds.doSth(new AdvStudent());Student s = new BaseStudent();//父类引用指向子类实例对象。ds.doSth(s);BaseStudent b = (BaseStudent)s;//将Student类型引用变量s强转成BaseStudent类型。b.play();}}


Object类,所有对象的直接或间接父类。

几个比较常见的方法:

boolean equals(Object obj) 
int hashCode() 返回该对象的哈希码值 
 void notify() 唤醒在此对象监视器上等待的单个线程。 
 void notifyAll() 唤醒在此对象监视器上等待的所有线程。 
String toString() 返回该对象的字符串表示。 
 void wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。 

内部类

将一个类定义在另一个类里面。一个事物里面还有事物的时候可以定义内部类。一般内部类都被私有化,通过对外提供方法进行访问。

访问特点
1,内部类可以直接访问外部类里的成员,包括私有成员。因为内部类中持有了外部类的引用:外部类名.this
2,外部类要访问内部类中的成员必须建立内部类的对象。
访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中,直接建立内部列对象。
建立格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象
          Outer.Inner in = new Outer().new Inner();

2,当内部类在成员位子上,就可以被成员修饰符所修饰。eg:private static
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。

访问静态内部类中的非静态成员function方法:new Outer.Inner().function();
访问静态内部类中的静态成员function方法:Outer.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的
当外部类中的静态方法访问内部类时,内部类也必须是static的

内部类定义在局部时:
1,不可以被成员修饰符修饰,则不能被私有,不能被静态。
2,虽然可以直接访问外部类中的成员。但是不可以访问它所在局部中的变量。只能访问被final修饰的局部变量。
class Outer{private int x = 0;class Inner(){int x =4;void function(){    int x =6;System.out.println(x);//System.out.println(Outer.this.x)}}void method(){//建立内部类对象,使用内部类方法。Inner in = new Inner();in.function();}}class InnerClassDemo{public static void main(String[] args){Outer out = new Outer();out.method();}} 
匿名内部类
前提:内部类必须是继承一个类或者实现接口。
格式:new 父类或者接口(){定义子类的内容}。

匿名内部类就是一个匿名子类对象。匿名内部类中定义的方法最好不要超过三个。

class Fu{public void print(){System.out.println("fu");}}public class Inner {public static void main(String[] args){//匿名内部类new Fu(){public void print(){System.out.println("zi");}}.print();}}打印的结果是:zi;

以上算是java中的定义一个类的语法和应该注意的地方。

接下来就是运行时应该注意的情况。

-----------android培训java培训、java学习型技术博客、期待与您交流! ------------