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() = 0Sub子类实际上包含了两个称为field的域,然而在引用Sub中的field时所产生的默认域并非Super版本的field域,因此为了得到Super.field,必须显式地指明super.field。
Java的一点内容(2)的更多相关文章
- Java 创建文本内容
Java 创建文本内容 import java.io.FileWriter; import java.io.IOException; public class TestFile { public st ...
- java读取文本文件内容2
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/183 很久之前写了一篇Java读取文本文件内容,链接地址是 ...
- java读取文本文件内容
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/128 java读取文本文件内容 今天写代码写着要调试一个很 ...
- java一点内容
1.JAVA有哪些基本数据类型 String是不是基本数据类型 Java语言提供了八种基本类型: 六种数字类型(四个整数型,两个浮点型) 字节型byte 8位 短整型short 16位 整型int 3 ...
- JAVA记录-JSP内容
JSP(JavaServer Pages )是什么? JavaServer Pages(JSP)是一种支持动态内容开发的网页技术它可以帮助开发人员通过利用特殊的JSP标签,其中大部分以<%开始并 ...
- java swing文件内容检索工具
Java相关技术 - 文件内容检索工具 拿到一个几百M甚至上G的project让你去学习 有时候你会想知道某个关键词是在哪个文件里 比如:spring MVC配置的@RequestMapping,你从 ...
- Java追加文件内容的三种方法
import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io. ...
- java读取word内容
暂时只写读取word内容的方法. 依赖的jar: poi-3.9-20121203.jarpoi-ooxml-3.9-20121203.jarxmlbeans-2.3.0.jar package co ...
- API例子:用Java/JavaScript下载内容提取器
1,引言 本文讲解怎样用Java和JavaScript使用 GooSeeker API 接口下载内容提取器,这是一个示例程序.什么是内容提取器?为什么用这种方式?源自Python即时网络爬虫开源项目: ...
随机推荐
- Altium Designer极坐标布局方法
1.键盘快捷组合 O+G,打开栅格管理器,点击左下角的“菜单”,在对话框中的选择“添加极坐标栅格”. 2.双击新添加的优先等级为1的栅格,在弹出的polar grid editor 对话框中,对里边 ...
- VC++深入详解读书笔记-第六章菜单
1.MFC都是采用大写字母来标识资源ID号. 2.程序中会用到多种资源,在为资源确定其ID号时,为了明确区分资源类型,一般都遵循这样一个原则:在“ID”字符串后加上一个标识资源类型的字母,例如,我们给 ...
- DHTML【2】--HTML
通过题目,大家已经明确知道,从这一节开始介绍DHTML中的最基础的部分HTML,对于HTML等概念上一节已经做了概述,这一节不再赘余.在学习HTML之前,先告诉大家一个好消息,HTML不难,比C++. ...
- MySql中查询表中的列名
例如我的数据库名为"example",使用 USE example; 确定使用example数据库.使用 show tables; 显示数据库中的所有表.使用 DESC perso ...
- 引入css外部样式表
前言 为什么会有这篇文章,外部引入样式有什么好谈的,不外乎就是 <link rel="stylesheet" href="style.css" /> ...
- ./configure 时候报错c++ 编译器不能执行
./configure时报错:configure: error: C++ compiler cannot create executables .哎,今天重装测试服务器上的系统,设置好IP可以远程访问 ...
- 汉诺塔问题C++实现
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang 以下进行汉诺塔问题的递归实现 #include <iostream.h> int gb ...
- 关于offsetWidth innerWidth的使用
最近因为有使用到offsetWidth 和innerWidth,刚开始以为这两个属性在jq何js之中是可以通用的,谁知道在js中使用innerWidth时,发现如果对页面元素使用它时,发现出来的是un ...
- 根据SVN的MESSAGE进行多版本输出,反向排序,真是曲折~~~啊
import os,sys,time file = open('svnlog') revList = [] tempList = [] linen = 1 for line in file: if ( ...
- Codeforces 540D Bad Luck Island
http://codeforces.com/problemset/problem/540/D 题目大意: 会出石头.剪刀.布的人分别有r,s,p个,他们相互碰到的概率相同,输的人死掉,问最终活下去的人 ...