黑马程序员_java面向对象


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


本章主要的知识点总结:1Java语言面向对象的三大特征,垃圾回收和Object类中clone()方法的介绍

                                        2、单例设计模式和内部类的介绍。

                                        3、重载和覆盖的区别,参数传递、关键字finalabstractnative的方法的应用                          4接口和异常的简介及访问控制符


一、 面向对象的三大特征


     封装  (Encapsulation),继承  (Inheritance),多态  (Polymorphism)

     模块设计追求强内聚(许多功能尽量在类的内部独立完成,不让外面干预),弱耦合(提供给外部尽量少的方法调用)。每个成员方法内部,都有一个this引用变量,指向调用这个方法的对象。


二、垃圾回收gc 方法和clone()方法


        System.gc(); 调用 gc 方法暗示着 Java 虚拟机做了一些努力来回收未用对象,以便能够快速地重用这些对象当前占用的内存。调用 System.gc() 实际上等效于用 Runtime.getRuntime().gc()。对象被回收之前会调用对象的finalize()方法,此方法是Object类的方法,子类可以重写。

         Object类中有一个clone()方法,可以获取对象的一份拷贝,返回类型是Object对象。

         如果一个类的对象需要支持拷贝(或者是克隆),那么这个类就需要实现Cloneable接口,然后需要重写clone()方法,并在该方法里面调用super.clone();

  public Object clone() throws CloneNotSupportedException {

    return super.clone();

    }    return super.clone();   }

         注意:拷贝对象中的变量时,对于引用类型的变量,拷贝的是引用地址,我们也可以对该引用所代表的类进行支持拷贝。

             Cloneable接口是标识接口,里面没有声明任何方法。为什么我们要在派生类中覆盖Object类中的clone()方法时,一定要调用super.clone()呢? 因为在运行时刻,Object中的clone()方法会自动识别出你要复制的是那一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象中的数据一一复制到新对象的存储空间中。

对于更深层一些的拷贝见如下例子:

public class CloneableTest {

 public static void main(String[] args) throws Exception {

  Professor professor = new Professor("教授1");

         CloneAttachment catt0 = new CloneAttachment("zhangsan", 20, professor);

         CloneAttachment catt1 = (CloneAttachment) catt0.clone();

           catt1.name = "lisi";

          catt1.age = 30;

           catt1.profe.name = "教授2";

           System.out.println(catt0);

           System.out.println(catt1);

 }

}

class CloneAttachment implements Cloneable {

          String name;

          int age;

          Professor profe;

 public CloneAttachment(String name, int age, Professor profe) {

           this.name = name;

           this.age = age;

           this.profe = profe;

 }

 public Object clone() throws CloneNotSupportedException {

           CloneAttachment camt = (CloneAttachment) super.clone();

           camt.profe = (Professor) profe.clone();

           return camt;

 } 

 public String toString() {

           return name + ":" + age + ":" + profe.name; }

}

class Professor implements Cloneable {

          String name;

          public Professor(String name) {

           this.name = name;

 }

 public Object clone() throws CloneNotSupportedException {

          return super.clone(); }

}

       如果一个类的对象需要被排序,例如:A[] aArr = new A[] {...}; Arrays.stor(aArr); 

那么A类必须实现Comparable接口,并且重写compareTo(Object obj)方法。如:

public int compareTo(Object o) {

           A a = (A)o;

           int retVal = 1;

           if(this.age < a.age) {

           retVal = -1 }        

 return  retVal;

}

          对已经进行过排序处理(Arrays.sort())的数组,我们可以用Arrays.binarySearch(...)方法来对数组进行搜索,返回一个数组索引值。

 

三、单例设计模式


当一个程序中用到了其他的类,类是在第一次被使用的时候才被加载,而不是在程序启动时就加载程序中所有可能要用到的类。一个类被加载的时候会执行类的静态代码块。static {...}

       如下是饿汉模式:

public class Singleton {

 private static final Singleton singleton = new Singleton();

 private Singleton() {}

 public static Singleton getInstance() {

            return singleton;

 }

}

如下是懒汉模式

public class Singleton {

 private static Singleton singleton = null;

 private Singleton() {}

 public static Singleton getInstance() {

  if(singleton == null) {

             singleton = new Singleton();  }

           return singleton; 

}

}


四、内部类的介绍


          嵌套类可以直接访问嵌套它的类的成员,包括private成员,但是嵌套类的成员却不能被嵌套它的类直接访问。一个内部类,不管它嵌套有多深,都可以访问外部类的所有成员。在内部类对象保存了一个对外部类对象的引用(Outer.this),当内部类的成员方法中访问某一变量时,如果在该方法和内部类中都没有定义过这个变量,内部类中对this的引用会被传递给那个外部类对象的引用。(即:this.变量不存在的情况下,传递给Outer.this.变量)

          如果用static修饰一个内部类,这个类就相当于是一个外部定义的类,所以static的内部类中可声明static成员,但是,非static的内部类中的成员是不能声明为static的。static的内部类不能再使用外层封装类的非static的成员变量.

内部类也可以是abstract类,也可以是final类。

内部类如何被外部引用:如下例子说明。

class Outer

{ private int size=10;

     public class Inner

     {    public void doStuff()

      {

          System.out.println(++size);   }

  }

}

public class TestInner

{

 public static void main( String[] args)

 {  Outer outer = new Outer();

            Outer.Inner inner = outer.new Inner();

            inner.doStuff();

 }

}

在类的外部需要派生内部类子类的程序代码如下:

public class NewInClassOverOutClass {

 public static void main(String[] args) {

            C c = new C(new A());

            c.sayHello(); }

}

class A {

 class B {

  public void sayHello() {

             System.out.println("hello");  }

 }

}

class C extends A.B {

 public C(A a) {

  a.super(); }

}


           嵌套类并非只能在类里定义,也可以在几个程序块的范围之内定义内部类。例如,在方法中,或甚至在for循环体内部,都可以定义嵌套类。

          在方法中定义的内部类只能访问方法中的final类型的局部变量,用final定义的局部变量相当于是一个常量,它的生命周期超出方法运行的生命周期。

          使用Java的文档注释:文档注释以“”标志结束,相应的信息和批注所对应的位置很重要!类的说明应在类定义之前,方法的说明应在方法的定义之前。 

批注参数来标记一些特殊的属性及其相应的说明 。

@author<作者姓名>

@version<版本信息>

@param<参数名称><参数说明>

@return<返回值说明>


 五、子类继承问题以及重载和覆盖的区别


          子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法。在子类的构造方法中可使用语句super(参数列表调用父类的构造方法。如果子类的构造方法中没有显式地调用父类构造方法(super(...)),也没有使用this关键字调用重载的其它构造方法,则在产生子类的实例对象时,系统默认调用父类无参数的构造方法。

子类对象的实例化过程:

     1、分配成员变量的存储空间并进行默认的初始化,就是用new关键字产生对象后,对类中的成员变量按第三章的表3.1中的对应关系对对象中的成员变量进行初始化赋值;

      2、绑定构造方法参数,就是new Person(实际参数列表)中所传递进的参数赋值给构造方法中的形式参数变量;

      3、如有this()调用,则调用相应的重载构造方法(被调用的重载构造方法又从步骤2开始执行这些流程),被调用的重载构造方法的执行流程结束后,回到当前构造方法,当前构造方法直接跳转到步骤6执行;

     4、显式或隐式追溯调用父类的构造方法(一直到Object类为止,Object是所有Java类的最顶层父类,在本章后面部分有详细讲解),父类的构造方法又从步骤2开始对父类执行这些流程,父类的构造方法的执行流程结束后,回到当前构造方法,当前构造方法继续往下执行;

     5、进行实例变量的显式初始化操作,也就是执行在定义成员变量时就对其进行赋值的语句;

      6、执行当前构造方法的方法体中的程序代码。

覆盖(重写)(Override)父类的方法:(三同,更宽,更小,更少)

       1、覆盖方法必须和被覆盖方法具有相同的方法名称、参数列表和返回值类型;

       2、覆盖方法时,不能使用比父类中被覆盖的方法更严格的访问权限;

       3、必须扔出父类方法抛出的相同的异常或异常的子类,或者不抛出异常;

       4、必须扔出父类方法抛出的那些异常的一个子集,也就是说不能扔出新的异常。

       5、如果在子类中想调用父类中的那个被覆盖的方法,我们可以用super.方法的格式。

方法重载(Overload):重载的方法,参数列表必须不相同(参数个数不同、参数类型不同、参数顺序不同,只要满足其一就表示参数列表不同。)其他无任何规定,重载的方法可以是返回值不同的,但是参数列表必须不相同。可以看如下例子:

public class OverloadTest {

 public void method() {

         System.out.println("无参数方法");

 }

 public void method(String str) {

         System.out.println("一个String类型的参数为:" + str);

 }

 public void method(int i) {

         System.out.println("一个int类型的参数为:" + i);

 }

 public void method(int i, String str) {

         System.out.println("两个参数,分别为int类型, String类型的参数为:" + i + ":" + str);

 }

 public void method(String str, int i) {

         System.out.println("两个参数,分别为String, int类型的参数为:" + str + ":" + i);

 }

 public int method(int i, int j) {

         return i + j;

 }

 public static void main(String[] args) {

         OverloadTest olt = new OverloadTest();

         olt.method();

         olt.method("hello");

         olt.method(999);

         olt.method(8, "haha");

         olt.method("haha", 9);

         System.out.println(olt.method(5, 15));

 }

}

六、参数传递、 关键字finalabstract关键字、native的方法


Java中,传递参数时,都是以传值的方式进行传递。

       1、对于基本数据类型:传递数据的拷贝;

      2、对于引用类型:传递引用地址的拷贝。 

Java中声明类、属性和方法时,可使用关键字final来修饰。

      1、 final标记的类不能被继承。

       2final标记的方法不能被子类重写。

       3final标记的变量(成员变量或局部变量)即成为常量,只能赋值一次。

       4、方法中定义的内置类只能访问该方法内的final类型的局部变量,用final定义的局部变量相当于是一个常量,它的生命周期超出方法运行的生命周期,将一个形参定义成final也是可以的,这就限定了我们在方法中修改形式参数的值。 

       5public static final共同标记常量时,这个常量就成了全局的常量。

       6、为了节约内存,我们一般情况下都把声明为final的变量同时也用static修饰。 因为声明为static的变量为类成员变量,不用为每个产生的实例对象做一份拷贝。

       7final变量一般在声明时初始化,也可以在构造函数中初始化。

       抽象类和抽象方法用abstract关键字修饰。声明为native的方法是本地方法,其中需要用到JNI(java native interface)JNIJava和本地应用程序的中介。还需要用到javah命令生成类的头文件。

       本地方法的主要目的是利用本地资源扩展Java功能,而与Java本身的机制无关。一个本地方法如同一个抽象方法,并没有实际的方法体,因为本地方法的实现不是Java语言,而是采用依赖本地平台的其他语言编写的位于Java虚拟机之外的函数库中,可通过System.loadLibrary()方法装入。System.loadLibrary()通常放置在静态初始化代码中。如果本地方法没有装载成功,则抛出UnsatisfiedLinkError异常。

       对本地方法的调用和Java中的其他方法一样的调用,本地方法的实现对调用者是透明的。实际上,在Object类上定义的clone()方法和notify()方法就是本地方法。

 

七、接口和异常的简介及访问控制符


1、接口是抽象方法和常量值的定义的集合

2、接口中的成员都是public访问类型的。接口中的变量默认是用public static final标识的。所以接口中的变量在其实现类中可以直接访问,也可以通过其实现类的实例去访问。 接口中的方法默认是用public abstract 修饰的。所以实现接口中的方法的时候需要声明为public的。

3、我们也可以定义一个类用implements关键字去实现一个接口中的所有方法,我们还可以去定义一个抽象类用implements关键字去实现一个接口中定义的部分方法。

4、一个接口可以继承自另一个接口,而且接口可以是多继承。如:

       interface Sofa extends Sittable, Lie {}

           运行时(RuntimeException)ArithmeticException, NullPointerException,

 IndexOutOfBoundsException等之类的异常可以不用显式的捕获或者抛出。如果我们编写的一个方法中有可能发生异常,那么就应该在方法后面声明要抛出异常,用throws <异常类1,异常类2,...>

异常有很多种,我们可以编写自己的异常类,这个类必须继承Exception类。

在程序中需要抛出自定义的异常,用throw关键字。

          finally语句块始终都会被执行,除非在trycatch中执行了System.exit(0);

小技巧:利用异常的处理机制,我们可以在一个方法中使用throwtrycatch语句来实现程序的跳转。

           类本身只能有两种访问控制符(内部类除外)public修饰的类能被所有的类访问,默认修饰(即class关键字前没有访问控制符)的类,只能被同一包中的所有类访问。

类成员中的访问控制修饰符有:

       private:   同一类

       (缺省):    同一类,同一包中的类

       protected: 同一类,同一包中的类,子类

       public:    所有类

                          

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值