Java的一点内容(2)

  • 1 面向对象的三个原则 封装性 封装的基本单元是类(class),类是一个抽象的逻辑结构,而类的对象是一个真实的物理实体;类的目的是封装复杂性,在类内部存在隐藏实现复杂性机制;
    封装(encapsulation) 的两个好处:
    模块化:可以独立于其他对象的源代码进行编写和维护,可以很容易的将对象在系统中传递;
    隐藏信息:其他对象可以通过本对象的一个公共接口进行通信而不影响其他对象;
      继承性 继承是一个对象获得另一个对象的属性的过程,继承机制是一个对象成为一个更具通用类的一个特定实例成为可能,避免了代码的重复编写;
      多态性 (重载overload,方法名相同、参数的个数不同、参数的类型不同、返回的类型不同和覆盖override) ;多态性就是“一种接口,多种方法”,可以为一组相关的动作设计一个通用的接口,其实类的函数的重载就是一种多态的体现;
    4 引入抽象编程的思想; 类的封装就是一种抽象思想
  • Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意味着通常情况下,我们不必判定是否应该进行动态绑定—它会自动发生。
    • final方法会使编译器生成更有效的代码,这也是为什么说声明为final方法能在一定程度上提高性能(效果不明显)。
    • 如果某个方法是静态的,它的行为就不具有多态性:

      class StaticSuper {
          public static String staticGet() {
              return "Base staticGet()";
          }
      
          public String dynamicGet() {
              return "Base dynamicGet()";
          }
      }
      
      class StaticSub extends StaticSuper {
          public static String staticGet() {
              return "Derived staticGet()";
          }
      
          public String dynamicGet() {
              return "Derived dynamicGet()";
          }
      }
      
      public class StaticPolymorphism {
      
          public static void main(String[] args) {
              StaticSuper sup = new StaticSub();
              System.out.println(sup.staticGet());
              System.out.println(sup.dynamicGet());
          }
      
      }
      

      输出:

      Base staticGet()
      Derived dynamicGet()

  • 构造函数并不具有多态性,它们实际上是static方法,只不过该static声明是隐式的。因此,构造函数不能够被override。
  • 在父类构造函数内部调用具有多态行为的函数将导致无法预测的结果,因为此时子类对象还没初始化,此时调用子类方法不会得到我们想要的结果。
    class Glyph {
        void draw() {
            System.out.println("Glyph.draw()");
        }
        Glyph() {
            System.out.println("Glyph() before draw()");
            draw();
            System.out.println("Glyph() after draw()");
        }
    }
    
    class RoundGlyph extends Glyph {
        private int radius = 1;
    
        RoundGlyph(int r) {
            radius = r;
            System.out.println("RoundGlyph.RoundGlyph(). radius = " + radius);
        }
    
        void draw() {
            System.out.println("RoundGlyph.draw(). radius = " + radius);
        }
    }
    
    public class PolyConstructors {
    
        public static void main(String[] args) {
            new RoundGlyph(5);
    
        }
    
    }
    

    输出:

    Glyph() before draw()
    RoundGlyph.draw(). radius = 0
    Glyph() after draw()
    RoundGlyph.RoundGlyph(). radius = 5

为什么会这样输出?这就要明确掌握Java中构造函数的调用顺序

(1)在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制0;
(2)调用基类构造函数。从根开始递归下去,因为多态性此时调用子类覆盖后的draw()方法(要在调用RoundGlyph构造函数之前调用),由于步骤1的缘故,我们此时会发现radius的值为0;
(3)按声明顺序调用成员的初始化方法;
(4)最后调用子类的构造函数。

    • 只有非private方法才可以被覆盖,但是还需要密切注意覆盖private方法的现象,这时虽然编译器不会报错,但是也不会按照我们所期望的来执行,即覆盖private方法对子类来说是一个新的方法而非重载方法。因此,在子类中,新方法名最好不要与基类的private方法采取同一名字(虽然没关系,但容易误解,以为能够覆盖基类的private方法)
    • Java类中属性域的访问操作都由编译器解析,因此不是多态的。父类和子类的同名属性都会分配不同的存储空间,如下:
      // Direct field access is determined at compile time.
      class Super {
          public int field = 0;
          public int getField() {
              return field;
          }
      }
      
      class Sub extends Super {
          public int field = 1;
          public int getField() {
              return field;
          }
          public int getSuperField() {
              return super.field;
          }
      }
      
      public class FieldAccess {
      
          public static void main(String[] args) {
              Super sup = new Sub();
              System.out.println("sup.filed = " + sup.field +
                      ", sup.getField() = " + sup.getField());
              Sub sub = new Sub();
              System.out.println("sub.filed = " + sub.field +
                      ", sub.getField() = " + sub.getField() +
                      ", sub.getSuperField() = " + sub.getSuperField());
          }
      
      }
      

      输出:

      sup.filed = 0, sup.getField() = 1
      sub.filed = 1, sub.getField() = 1, sub.getSuperField() = 0

      Sub子类实际上包含了两个称为field的域,然而在引用Sub中的field时所产生的默认域并非Super版本的field域,因此为了得到Super.field,必须显式地指明super.field。

时间: 2024-10-12 13:31:58

Java的一点内容(2)的相关文章

自己对Java的一点看法

作为一个理论性比较强的学生,谈一下这段时间对java以及对程序设计的理解 java相对于其它语言有几个特点,一个是面向对象,一个是强类型           首先谈谈面向对象,关于类和对象,这个一定要有深刻的认识,在类中,首先一个最重要的概念就是构造方法,为什么说它重要,就是因为你只要需要创建一个类地实例对象就需要调用到构造方法,这个就决定了这个类一开始要做什么,还是举一个例子吧         比如说BrfferedReader类,这个的构造方法就是BrfferedReader(Reader

【Java】无须额外的包,把Java中的内容输出到Excel中,无乱码,绝对兼容Excel2003与2007

Java输出一段文本到txt中大家基本都会了,这已经是学习Java的必修课了,不会也没有问题,具体可以看<[Java]输入与输出与JDK1.5之后的新型字符串StringBuilder>(点击打开链接).网上对于Java内容转化成Excel的内容大多数都是需要什么poi包,jsl包,一堆奇奇怪怪的jar插件.其实仅仅利用java.io.*;这个基本包就能够把Java中的内容输出到Excel表中,当然,如果你是要处理Mysql数据库不要这样做了,直接一条Mysql的查询命令就能把Mysql的查询

面试题目java读取文本内容方式

面试题目java读取文本内容方式二种方式 第一种通过FileInputStream()方式读取 FileInputStream fis = new FileInputStream("a.txt"); //创建流对象 byte[] arr = new byte[4]; int len; while((len = fis.read(arr)) != -1) { System.out.print(new String(arr,0,len)); } fis.close(); 第二种通过:Fil

java一点内容

1.JAVA有哪些基本数据类型 String是不是基本数据类型 Java语言提供了八种基本类型: 六种数字类型(四个整数型,两个浮点型) 字节型byte 8位 短整型short 16位 整型int 32位长整型long   64位 单精度float 32位   双精度double 64位 一种字符类型 字符型char 8位 还有一种布尔型. 布尔型:boolean 8位 可存储"True"和"false" String str1 = "x" ;

关于Java的一点感悟---底层开发者的上层学习感悟

这些年主要一直是搞C.C++,偏底层一些,一直想多了解一下上层的东西.于是利用业余时间,看了些Java方面的东西,也利用一些架构搭建了一些简单的程序,在此想简单的谈谈自己的一点感悟. 1.Java真的是非常方便.对于做惯了底层的我,依靠文档在文本编辑器中写程序,已经成为了习惯.一下子转换到Java这种集成环境中,感觉简直是方便太多了.连文档都用不上了,光自动提示的信息就够解决普通问题了.写起来代码,感觉行云流水,非常的流畅. 2. Java的各种库非常的多,多数也是开源的.给人的感觉是只有想不到

java 编程一点心灵体会

近来,一直在思考如何提高自己的编码,主要敲,但是问题也出在,如果是怎么敲!  问题出在只是一直在照着视频敲,完全没有自己的思路,像StringBuffer st = new StringBuffer(),  System.out.println();  这么简单的能敲出来, 还有就是xml 解析, webservice接口 之类的  还有一些  简单的 js,  会一点点的document.getElementById.value, 还有jquery 看过完整的视频  只敢说会敲一点点,  不敢

Java解析文件内容

本文主要实现对.chk文件的解析,将其内容读出来,存入到一个Map中,文件内容实例为: A0500220140828.CHK A05002 |34622511 |373532879 |3 识别分隔符|,代码如下所示: 1 package com.src.factory; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileReader; 6 import java.io.IOExceptio

每天进步一点----- 内容提供者ContentProvider

一个简单的读取系统联系人 package com.example.contactstest; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.provider.ContactsContract; import android.widget.ArrayAdapter; import android.widget.ListView; import android.a

Java大部分的内容

写在前面: 过去,我学习Java的时候,全部采取的是“短平快”的培训教材: 1.  它们会把重点列举出来 2.  在学校里老师不看基础,只看到你做了什么产品 现在工作了,觉得工作的内容并没有什么难度,多出来的时间,巩固基础. 正文: 先说一句话: 只会Java并不可耻   (即使你不仅仅只会Java) 1. <Java自学教程>  快速根据例子把Java大部分内容 遍历一遍. 2. <Java语言程序设计>(基础篇和进阶教程) 3.  辅助教材<疯狂Java精髓>  (