随笔-159  评论-114  文章-7  trackbacks-0
面向对象高级

static,可以修饰属性、方法、代码块。

每个对象称为类的实例,对象之间的存储区互不干涉。

static int data;是类变量(共享),为类开辟一个空间。共享存储区域。

访问类变量,通过类名访问。一个对象引用也可以使用静态成员,与它的编译时类型的类访问,一致。

MyClass m = new MyClass();
m.data 《= 》MyClass.data;

静态方法-〉没有当前对象概念-〉也就不允许访问的类中的非静态成员(实例变量)

主方法之所以是静态的,它是程序入口,JVM最初没有对象,必须通过使用类名调用方法,主方法必须为静态的。

静态方法不能被覆盖。

静态代码块只执行一次。

static 用于单例模式Singleton模式

class DBConnection{
   
private static DBConnection db = null;
   
private DBConnection{}

   
public static DBConnection getInstance(){
         
if(db == null) db = new DBConnection();
         
return db;
   }

}


final 修饰  类、属性、方法

修饰类,无子类,保证用户使用的一致性。典型范例String类。

修饰属性或者变量一旦赋值,不得更改。

对于对象变量来说,是不能再指向其他对象,而现有的对象内部属性可以改变。

会配合static一起使用,只分配一个存储空间,只需要维护一个空间。

public static final,是一个常量。大写。

class SuperClass{
      final int AGE;

      public SuperClass(){
         AGE=10;
      }
}

初始值0不算,需要显示赋一次值。

初始设定在两个地方,1定义时直接赋值,2构造器

静态常量也在两个地方设定,1初始设定,2静态代码块




final方法不能覆盖,由于多态,一个编译时类型对应多个运行时类型,final保证某方法的稳定性。


private
               左边的修饰符有其中一个,系统都默认添加了final修饰符。
static


所以之前的静态方法不能覆盖。

=====================
方法继承是决定于在子类中是否可见。能见到就是继承。

final不决定继承。

实际上如果实例化一个子类对象,它的父类对象的所有属性(包括private成员都创建了,就是访问不了,所以不能成为继承的一部分,也就是不能继承咯)



=====================


abstract 修饰 类 方法

修饰类 -> 这个类必须被继承使用->不能生成对象

用处,把子类最大的共性提取出来放入其中,面向对象一般原则。

虽然不能生成对象(不能作为运行时类型),但可以声明为类型(可作为编译时类型)。

抽象方法,没有实现,留给子类覆盖。

final永远不可能和abstract在一起,那么private和static也不能和abstract联合修饰。

final表示必须不能被继承,不能覆盖;abstract表示必须继承,方法没有实现,必须覆盖使用。所以矛盾。

abstract class SuperClass{
      abstract void print(); //print(){},这是空实现,也是实现,所以不能带大括号。
}

如果类中有抽象方法的话,那么类只能是抽象类。(一个半成品)

如果子类没有实现父类的抽象方法,就会编译出错,因为子类继承了抽象方法,需要声明为抽象类。

SuperClass sc = new SubClass();

sc.print();动态类型判定,运行时类型不会改变,肯定是一个实现抽象方法的类对象。




接口:是同类,同一个层次的数据结构。

interface IA{
   void print();  
   int A = 1;
}

修饰符省略
一个Java文件,只能定义一个公开接口

一个接口等同于一个抽象类

一个特殊的抽象类:
   所有方法都是公开抽象的:public abstract
   所有属性都是公开静态常量:public static final

interface IA{
   void print();  
   int A = 1;
}

等价于

abstract class IA{
   public static final int A=1;
   public abstract void print();
}

这时可要注意,类实现接口时,覆盖方法的访问控制符一定要写上public,接口是省略为public,类不写可是default,根据Overriding规则,覆盖方法的访问控制等于或者大于父类方法的访问控制。

class IAImpl extends java.util.ArrayList implements IA{}

1一个类除了继承类,还可以实现接口(多个)。

2尽管一个类只能继承一个类,一个类可以实现多个接口

3接口与接口之间可以继承并可以多继承,实现多重继承,但复杂度不增加。

interface IC extends IA,IB{}

IC有着IA,IB所有方法的定义

IA,IB可以作为编译时类型。

========================

接口,被用来定义可以***的东西。

                  存储设备                              输入设备
----|----------------|-----                     ----------|-----------
硬盘                  U盘                                 鼠标
----|----
移动硬盘

使用接口来剥离出一部分抽象。

移动硬盘、U盘、鼠标除了间接父类是统一的设备父类外。

他们都是USB设备,这部分抽象就需要用接口定义。

那么机器上的连接器是一个方法,connect(USB接口),不管你什么具体设备,你都必须实现USB规范,才能往上插。

那么用接口来定义一个规范。


例子2,JDBC,使用Java来访问数据库。

首先,如果由Sun公司自己提供各种数据库的驱动,那么各个DB厂商需要把数据库核心代码提供给Sun,这是不可能的,核心商业机密。

而由各个DB厂商自己写的话,会出现方法名的不同,导致如果数据库迁移,代码需要改动。(例如Oracle提供的方法为ConnectOracle()而ms提供的方法为ConnectSQL)。那么无法真正实现Write Once,Run Anywhere,Sun不同意。

怎么办?使用接口。

由Sun和DB联合制定一些一系列接口。

interface Driver()
{
      void connect();
      ...
}

OracleDriver implements Driver
SQLDriver implements Driver

实现不同的connect()逻辑。

用户Driver d = getDriver();
d.connect();

接口是实现Java一次编译,到处运行的重要技术。

保证了Sun制定规范,数据库厂商实现,用户使用。保证架构稳定性(将三方分开)

对于用户来说,接口最大化屏蔽差异。

1.实现不同层次,不同体系的对象的抽象。
2.保证架构稳定性。对用户透明。


==============================

Object 类,所有类的父类(直接,间接父类)

finalize(),当一个对象被垃圾回收的时候,会调用一下。不适合放入释放资源的方法。

toString(),对象的字符串表现形式。

System.out.println(obj);->obj.toString()

自定义类,覆盖该方法,返回一些有意义的信息。

==  判断字面值是否相等,

String a = new String("hello");
String b = new String("hello");
b==a false

String final类,并且它的值也是immutable的。

String a = "A"
a = a + "B"
这两步操作一共产生了3个对象。

JVM内部有一个字符串池,一个独立存储区域,保存已创建的字符串,如果再有相同的,会将引用指向字符串池中的已有对象,不再创建新的,如果没有再创建。

String a = "abc";
String b = "abc";

所以上面的例子是采用new String("abc")方式创建String对象,不会再去池中找,直接在堆中创建新对象。

String a = new String("hello");
String b = "hello";

a为堆地址,b为串池地址,a==b,false。

这种方式,是一种用时间换空间的做法,比如如果程序中有100个"hello",难道程序要去维护100个对象嘛。

Object.equals   判断对象值是否相等。

/*
 * Student.java
 *
 * Created on 2005年12月3日, 上午10:43
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 
*/


package javaapplication1;

/**
 *
 * 
@author Administrator
 
*/

public class Student {
    
    String name;
    
int age;
    
    
/** Creates a new instance of Student */
    
public Student() {
    }

    
    
public Student(String n,int a){
        
this.name = n;
        
this.age = a;
    }

    
    
public boolean equals(Object o)
    
{
        Student s 
= (Student)o;
        
if(s.name.equals(this.name)&&s.age == this.age)
            
return true;
        
return false;
    }

    
}

自定义类如果要进行对象值的比较,覆盖Object的equals方法,自行判断,如果不覆盖,直接调用Object.equals是判断地址。

equals方法覆盖标准流程:

    public boolean equals(Object o)
    
{
        
if(this == o)
            
return true;
        
if(o == null)
            
return false;
        
if(!(o instanceof Student))
            
return false;
        Student s 
= (Student)o;
        
if(s.name.equals(this.name)&&s.age == this.age)
            
return true;
        
return false;
    }

double d = 10000.0d;
Double D_d 
= new Double(d);
String D_S 
= D_d.toString();//D + ""
String d_s = String.valueOf(d);//d + ""
double s_d = Double.parseDouble(d_s);
Double S_D 
= Double.valueOf(d_s);
double d_D = D_d.doubleValue();












 



posted on 2005-12-02 00:03 北国狼人的BloG 阅读(380) 评论(0)  编辑  收藏 所属分类: 达内学习总结

只有注册用户登录后才能发表评论。


网站导航: