码迷,mamicode.com
首页 > 其他好文 > 详细

4:面向对象高级

时间:2015-10-26 16:59:47      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:


继承弊端:打破了封装性。

final关键字:
1,final是一个修饰符,可以修饰类,方法,变量。
2,final修饰的类不可以被继承。
3,final修饰的方法不可以被覆盖。
4,final修饰的变量是一个常量,只能赋值一次。
 为什么要用final修饰变量。其实在程序如果一个数据是固定的,
 那么直接使用这个数据就可以了,但是这样阅读性差,所以它该数据起个名称。
 而且这个变量名称的值不能变化,所以加上final固定。
写法规范:常量所有字母都大写,多个单词,中间用_连接。


抽象类
抽象:笼统,模糊,看不懂!不具体。
特点: 
1,方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰。
 抽象方法必须定义在抽象类中。该类必须也被abstract修饰。
2,抽象类不可以被实例化。为什么?因为调用抽象方法没意义。
3,抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化。
 否则,这个子类还是抽象类。


1,抽象类中有构造函数吗?
 有,用于给子类对象进行初始化。
2,抽象类可以不定义抽象方法吗? 
 可以的。 但是很少见,目的就是不让该类创建对象。AWT的适配器对象就是这种类。
 通常这个类中的方法有方法体,但是却没有内容。
  1. abstract class Demo
  2.  {
  3.   void show1()
  4.   {}
  5.   void show2() 
  6.   {}
  7.  }
3,抽象关键字不可以和那些关键字共存? 
 private 不行 ,private进行了封装
 static 不行 ,通过类名.方法调用没有意义
 final 不行,final代表最终的,不能被重写
4,抽象类和一般类的异同点。 
 相同点:
  抽象类和一般类都是用来描述事物的,都在内部定了成员。
 不同:
  1,一般类有足够的信息描述事物。
     抽象类描述事物的信息有可能不足。
  2,一般类中不能定义抽象方法,只能定非抽象方法。
     抽象类中可定义抽象方法,同时也可以定义非抽象方法。
  3,一般类可以被实例化。
     抽象类不可以被实例化。
5,抽象类一定是个父类吗? 
 是的。因为需要子类覆盖其方法后才可以对子类实例化。 


接口
定义接口使用的关键字不是class,是interface.
/*
对于接口当中常见的成员:而且这些成员都有固定的修饰符。
1,全局常量: public  static final
2,抽象方法。public abstract  
由此得出结论,接口中的成员都是公共的权限.
  1. interface Demo
  2. {
  3.  public static final int NUM = 4;
  4.  public abstract void show1();
  5.  public abstract void show2();
  6. }
类与类之间是继承关系,类与接口直接是实现关系。
接口不可以实例化。 
只能由实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实例化。 
否则,这个子类就是一个抽象类。

修饰符 class 类名 extends 父类implements 接口1,接口2。。。

{类体部分 ,如果继承了抽象类,需要实现继承的抽象方法;要实现接口中的抽象方法}

  1. interface QQ extends  CC,MM//接口与接口之间是继承关系,而且接口可以多继承。
  2. {
  3.  void function();
  4. }
  5. class WW implements QQ
  6. {
  7. //覆盖3个方法。
  8.  public void show(){}
  9.  public void method(){}
  10.  public void function(){}
  11. }
抽象类和接口的异同点:
相同点: 
 都是不断向上抽取而来的。
不同点: 
 1,抽象类需要被继承,而且只能单继承。
    接口需要被实现,而且可以多实现。
 2,抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。
    接口中只能定义抽象方法,必须由子类去实现。
 3,抽象类的继承,是is a关系,在定义该体系的基本共性内容。
    接口的实现是 like a 关系,在定义体系额外功能。


多态
对象的多态性。
class 动物 
{}
class 猫 extends 动物 
{}
class 狗 extends 动物 
{}
猫 x = new 猫(); 
动物 x = new 猫();//一个对象,两种形态。 
猫这类事物即具备者猫的形态,又具备着动物的形态。 
这就是对象的多态性。
简单说:就是一个对象对应着不同类型.
多态在代码中的体现: 
 父类或者接口的引用指向其子类的对象。
多态的好处:
 提高了代码的扩展性,前期定义的代码可以使用后期的内容。
多态的弊端: 
 前期定义的内容不能使用(调用)后期子类的特有内容。
多态的前提:
 1,必须有关系,继承,实现。
 2,要有覆盖。 


Animal a = new Cat(); //自动类型提升,猫对象提升了动物类型。但是特有功能无法访问。
作用就是限制对特有功能的访问。
专业讲:向上转型。将子类型隐藏。就不用使用子类的特有方法。
如果还想用具体动物猫的特有功能。
你可以将该对象进行向下转型。
 Cat c = (Cat)a;//向下转型的目的是为了使用子类中的特有方法。
c.eat();
c.catchMouse();
注意:对于转型,自始自终都是子类对象在做着类型的变化。 
  1. public static void method(Animal a)
  2.  {
  3.   a.eat();
  4.   if(a instanceof Cat)//instanceof:用于判断对象的具体类型,只能用于引用数据类型判断 
  5. //通常在向下转型前用于健壮性的判断, 如果传入了其他的东西就不能调用
  6.   { 
  7.    Cat c = (Cat)a;
  8.    c.catchMouse();
  9.   }
  10.   else if(a instanceof Dog)
  11.   {
  12.    Dog d = (Dog)a;
  13.    d.lookHome();
  14.   }

技术分享
多态时, 成员的特点: 
1,成员变量。
 编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。
 运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。
 简单说:编译和运行都参考等号的左边。哦了。
 作为了解。
2,成员函数(非静态)。 
 编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。
 运行时:参考的是对象所属的类中是否有调用的函数。
 简单说:编译看左边,运行看右边。
因为成员函数存在覆盖特性。 
技术分享
3,静态函数。 
  编译时:参考引用型变量所属的类中的是否有调用的静态方法。
  运行时:参考引用型变量所属的类中的是否有调用的静态方法。
  简单说,编译和运行都看左边。
  其实对于静态方法,是不需要对象的。直接用类名调用即可。


内部类
内部类访问特点:
1,内部类可以直接访问外部类中的成员。
2,外部类要访问内部类,必须建立内部类的对象。

一把用于类的设计。
分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容。 
这时就是还有的事物定义成内部类来描述。
  1. class Outer
  2. {
  3.  private static int num = 31;
  4.  class Inner// 内部类
  5.  {
  6.   void show()
  7.   {
  8.    System.out.println("show run..."+num);
  9.   }
  10.   /*static void function()//如果内部类中定义了静态成员,该内部类也必须是静态的
  11.   {
  12.    System.out.println("function run ...."+num);
  13.   }
  14.   */
  15.  }
  16.  public void method()
  17.  {
  18.   Inner in = new Inner();
  19.   in.show();
  20.  }
  21. }

在类的外部如何访问内部类对象?
对于非静态内部类

①先创建外部类对象,然后再创建内部类对象

OuterClass oc=new OutClass();

InnerClass ic=oc.new InnerClss();

ic.test();


class InnerClassDemo
{
 public static void main(String[] args)
 {
 Outer out = new Outer();
out.method(); 这是创建一个方法访问
直接访问外部类中的内部类中的成员。
Outer.Inner in = new Outer().new Inner();
in.show();


静态内部类:内部使用static来修饰,所以创建该类的对象可以没有外部类对象
 如果内部类是静态的。 相当于一个外部类
Outer.Inner in = new Outer.Inner();
 in.show();

如果内部类是静态的,成员是静态的。
Outer.Inner.function();
 } 
}



为什么内部类能直接访问外部类中成员呢?
那是因为内部类持有了外部类的引用。  外部类名.this
class Outer
{
 int num = 1;
 class Inner
 {
  int num = 2;
  void show()
  {
   int num = 3;

  System.out.println(num);//3
 System.out.println(this.num);//2
 System.out.println(Outer.this.num);//1
 如果外部成员变量是int a=1,这里直接写就行,即名称不一样的时候上面这样写

 }
 }
 void method()
 {
  new Inner().show();//匿名对象
 }
}

class InnerClassDemo2
{
 public static void main(String[] args)
 {
  new Outer().method();
 }
}
注意:静态内部类中的方法不能访问外部内的非静态成员


内部类可以存放在局部位置上。
内部类在局部位置上只能访问局部中被final修饰的局部变量。
  1. class Outer 
  2. {
  3.  int num = 3;
  4.  Object method()
  5.  {
  6. final int x = 9; 
  7.   class Inner 
  8.   {
  9.    public String toString()
  10.    {
  11.     return "show ..."+x;
  12.    }
  13.   }

匿名内部类。就是内部类的简写格式。
在类的内部直接创建一个接口的实现类对象  
 必须有前提: 
 内部类必须继承或者实现一个外部类或者接口。
匿名内部类:其实就是一个匿名子类对象。  
格式:new 父类or接口(){子类内容}
  1. abstract class Demo
  2. {
  3.  abstract void show();
  4. }
  5. class Outer
  6. {
  7.  int num = 4;
  8.  /* 正常情况
  9.  class Inner extends Demo
  10.  {
  11.   void show()
  12.   {
  13.    System.out.println("show ..."+num);
  14.   }
  15.  }
  16.  */
  17.  public void method()
  18.  {
  19.   //new Inner().show();
  20.   
  21. new Demo()//匿名内部类。 直接内容写进去
  22.   {
  23.    void show()
  24.    {
  25.     System.out.println("show ........"+num);
  26.    }
  27.   }.show(); //可以调用,也可以不调用
  28.  }
  29. }
  30. class InnerClassDemo4
  31. {
  32.  public static void main(String[] args)
  33.  {
  34.   new Outer().method();
  35.  }
  36. }

通常的使用场景之一:
当函数参数是接口类型时,而且接口中的方法不超过三个。
可以用匿名内部类作为实际参数进行传递?
不是太懂,参见day10 InnerClassDemo5.java
  1. class Outer
  2. {
  3.  void method()
  4.  {
  5.   Object obj = new Object() //匿名内部的特征就是直接在()后写内部内容
  6.   {
  7.    public void show()
  8.    {
  9.     System.out.println("show run");
  10.    }
  11.   };
  12.   obj.show();//因为匿名内部类这个子类对象被向上转型为了Object类型。
  13.      //这样就不能在使用子类特有的方法了。
  14.  } 
  15. }
  16. class InnerClassDemo6
  17. {
  18.  public static void main(String[] args)
  19.  {
  20.   new Outer().method();
  21.  }
  22. }

Eg:

New IplayGame(){

Public void playGame(){

Sysout(用匿名内部类实现接口)}

}.playGame();

也可以在类的内部这样写:

IplayGame ip= new iplayGame(){

   Public void playGame(){

   Sysout(使用匿名内部类实现接口)}};

   Ip.playGame();//通过这样访问这个方法


Object类:

它是所有类的根父类

  1. Object类的变量可以指向任何类型的对象
  2. Object是不断抽取而来,具备着所有对象都具备的共性内容。
  3. Objict的方法,参数类型是Object类型,所以可以传入任何参数

默认为:Object obj=new person()

==和equals:

1.==:对于引用类型,表叫俩个对象的内存地址是否相同,要求俩边对象是类型兼容的,若不兼容,则编译出错

2.Object类的equals方法:原义是比较俩个对象的内存地址是否相同,可以传入任何对象,通常情况我们

是比较俩个参数的值是否相同,所以可以根据业务的需要重写该方法,步骤:

Public boolean equals(object obj)

①检验传入的为person类型,若不是,直接返回false

If(!(Obj instanceof person))

Return false;

②若是person类型,则先进行强制转换

Person person=(person)obj

③比较name和age

If(name.equals(person.name)&&age==person.age)

Return ture;

Return false;


Tostring()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址(哈西码)

在进行String与其他类型数据连接操作时,自动调用tostring()方法

Date now=new date();

Sysout(now)相当于sysout(now.tostring())

输出的是date@12332

一般开发时重写该方法

S1=hello

Sysout(s1)

技术分享


System.out.println(p1.toString());//Person@61de33

hashCode方法

当equals方法重写时,通常有必要重写hashcode方法 ,因为内容相同,地址也得相同,才能叫一样

getClass方法

获取当前对象所属的字节码文件对象

技术分享

Class clazz1 = p1.getClass();

Class clazz2 = p2.getClass();

System.out.println(clazz1==clazz2);

System.out.println(clazz1.getName());

技术分享

getClass().getName()获取字节码文件对象的名称:person

getClass().method()获取字节码文件对象的方

System.out.println(p1.getClass().getName()+"$"+Integer.toHexString(p1.hashCode()));//Person@61de33

Integer.toHexString:10进制转换16进制,工作时经常用,因为能短点
技术分享




4:面向对象高级

标签:

原文地址:http://www.cnblogs.com/liuyu0529/p/4911606.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!