未知数据

从头看Java

   ::  :: 联系 :: 聚合  :: 管理
  28 Posts :: 0 Stories :: 10 Comments :: 0 Trackbacks

1. 类和对象

  

     类可以认为是自定义的数据类型,.类用于描述某一类对象的共同特征,对象是类的具体存在.

 

java中的对象及其属性数据是存放在堆(heap)内存中的,而引用变量则是存放在栈内存中的.

    Person p = new Person();

    系统会生成两个实体,一个是引用变量p,一个是Person对象.栈内存中的引用变量p指向堆内存中的Person对象,变量p只是存储了一个地址值,本身不包含任何实际数据.堆内存中的数据不允许直接访问,只能通过该对象的引用去访问该对象.

    Person p1 = p;

    将p变量赋给p1,也就是将p变量保存的地址值赋给p1.这样p1也指向了堆内存中的同一个对象,这样不管是通过p还是p1访问对象的属性和方法,结果都是访问同一个对象的属性和方法,返回的结果都是一样的.也就是说堆内存中的对象可以有多个引用.

    p = null;

    当堆内存中的某个对象没有引用执行它时,程序将无法再访问到这个对象,这个对象也就是无用的了,垃圾回收机制将回收这个对象,释放该对象所占用的内存空间.因此,如果需要垃圾回收机制回收某个对象,只要切断该对象的所有引用即可,也就是将相关的引用赋为null.

内存示意图:

2. 面向对象的特征

    1. 封装

     对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问.类似客观世界中的属性都是隐藏在对象内部的,外部无法直接操作和修改.良好的封装是通过对外暴露足够的方法来操作和访问类的内部信息.

  访问控制级别从private到public逐次变大

 

    2. 继承

       1. java不支持多重继承,每个子类只有一个直接父类

       2. Object类是一切类的父类

       3. 子类继承不能继承父类的私有的成员变量和成员方法.

           在抽象类中定义了私有的成员方法或变量,子类不能访问到父类的私有成员,所以子类中重写父类的私有方法,实际上是新建了一个方法;在接口定义中的成员是不能为私有的,否则编译会报错,因为接口是用来公开的,私有的变量和方法不能被继承或实现.

       4. 覆盖和被覆盖的方法必须同是实例方法或同时类方法

       5. 子类中的变量可以覆盖父类中同名的变量,但并不是覆盖,而只是屏蔽,父类的变量并未改变

       6. 调用子类构造方法之前,系统会先调用父类的构造方法,如果有多个父类,则从上到下依次调用

       7. 内存机制中,父类和子类是占用同一块内存空间的,只是子类在父类的基础上增加自己的属性和方法.

       8. 在子类中可通过super访问父类中的成员.

       9. 系统创建某个类的对象时,系统总会隐式地创建该类父类的对象.在子类方法中,super指向该方法调用者的子类对象的父类对象.

代码清单: 继承

abstract class A {    
      int i=1;    
      public void printI() {    
        System.out.println("i="+i);    
      }    
}    
       
    public class B  extends A{    
      int i=2;    
      public void printI() {
          super.printI();
      }
      public static void main(String[] args) {    
        B b=new B();    
        b.printI();    //i=1;
      }    
    }  

 3. 多态

     1. 相同类型的变量,执行同一个方法时呈现出不同的行为特征,就是多态.多态发生在编译时类型和运行时类型不一致时.

     2. 引用类型在编译阶段只能调用其编译时类型所具有的方法,运行时则执行它运行时类型所具有的方法

     3. 引用变量只能调用声明该变量的所用的类包含的方法,通过引用变量只能访问到编译时类所定义的属性.

     例如 BaseClass bsc = new SubClass()通过变量bsc只能调用BaseClass所定义的方法,而不能访问sub(),所以bsc.sub()会编译不通过.可以通过bsc访问test(),但运行时调用的是SubClass类的方法.通过bsc访问的属性book是BaseClass的属性.

 
class BaseClass {
    
    public int book = 1;
    
    public void base() {
        System.out.println("父类的普通方法");
    }
    
    public void test() {
        System.out.println("父类被覆盖的方法");
    }
    
}
 
public class SubClass extends BaseClass{
    
    public String book = "JAVA";
    
    public void test() {
        System.out.println("子类覆盖父类的方法");
    }
    
    public void sub() {
        System.out.println("子类的普通方法");
    }
 
    public static void main(String[] args) {
 
        System.out.println("=======BaseClass bc = new BaseClass();=======");
        BaseClass bc = new BaseClass();
        System.out.println(bc.book);
        bc.test();
        bc.base();
        
        System.out.println("=======SubClass sc = new SubClass();=======");
        SubClass sc = new SubClass();
        System.out.println(sc.book);
        sc.test();
        sc.base();
        
        System.out.println("=======BaseClass bsc = new SubClass();=======");
        
        BaseClass bsc = new SubClass();// 编译时类型和运行时类型不一致时,发生多态
        System.out.println(bsc.book);//打印:1,对象的属性不具有多态性,只能访问编译时类型中的属性
        bsc.test();//子类覆盖父类的方法,运行时调用的是运行时类型所定义的方法.
        bsc.base();//父类的普通方法
        //bsc.sub();// 只能访问编译时类型中所定义的方法
        
    }
 
}
posted on 2009-01-14 23:01 wangjc 阅读(217) 评论(0)  编辑  收藏 所属分类: 从头看Java

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


网站导航: