继承:
父类(SuperClass)和 子类(SonClass)。
父类的非私有化属性和方法可以默认继承到子类。
Class Son extends Father{}
而如果父类中的私有方法被子类调用的话,则编译报错。
父类的构造方法子类不可以继承,更不存在覆盖的问题。(非构造方法可以)
如果子类访问父类的构造方法,则在编译的时候提示访问不到该方法。
JAVA中不允许多继承,一个类有且只有一个父类(单继承)。
JAVA的数据结构为树型结构,而非网状。(JAVA通过接口和内部类实现多继承)
方法的覆盖(overriding)
方法的重载并不一定是在一个类中:子类可以从父类继承一个方法,也可以定义一个同名异参的方法,也称为overloading。
当子类从父类继承一个无参方法,而又定义了一个同样的无参方法,则子类新写的方法覆盖父类的方法,称为覆盖。(注意返回值类型也必须相同,否则编译出错。)
如果方法不同,则成重载。
对于方法的修饰词,子类方法要比父类的方法范围更加的宽泛。父类为public,那么子类为private则出现错误。
之所以构造方法先运行父类再运行子类是因为构造方法是无法覆盖的。
以下范围依次由严到宽:
private :本类访问;
default :表示默认,不仅本类访问,而且是同包可见。
Protected:同包可见+不同包的子类可见
Public :表示所有的地方均可见。
当构造一个对象的时候,系统先构造父类对象,再构造子类对象。
构造一个对象的顺序:(注意:构造父类对象的时候也是这几步)
① 递归地构造父类对象;
② 顺序地调用本类成员属性赋初值语句;
③ 本类的构造方法。
Super()表示调用父类的构造方法。
Super()也和this一样必须放在第一行。
This()用于调用本类的构造方法。
如果没有定义构造方法,那么就会调用父类的无参构造方法,即super()。
要养成良好的编程习惯:就是要加上默认的父类无参的构造方法。
=========================================-=========================================-=========================================-
int,double,long这些都是基本数据类型,不具备对象的特性。一个对象就有属性和行为,但是基本数据类型没有。
java中的Integer就是int的包装类,它定义的变量就是对象类型了,有属性和行为。
int.class只是int 的 Class对象,也就是说int.class是一个Class对象
API帮助文档中所描述的:
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
数组反射
如果因为某种原因,并不确定参数或对象是不是数组,可以检索对象的 Class 对象并询问它。 Class 类的 isArray() 方法将会告诉您。一旦知道拥有了一个数组,就可以询问 Class 的 getComponentType() 方法,实际拥有的是什么类型的数组。如果 isArray() 方法返回 false,那么 getComponentType() 方法返回空。否则返回元素的 Class 类型。如果数组是多维的,可以递归调用 isArray() 。它将仍只包含一个 component 类型。此外,可以用在
java.lang.reflect 包里找到的 Array 类的 getLength() 方法获取数组的长度。
为了演示,清单 2-3 显示了传递给 main() 方法的参数是 java.lang.String 对象的数组,其中数组长度由命令行参数的个数确定:
清单 2-3. 使用反射检查数组类型和长度
public class ArrayReflection {
public static void main (String args[]){
printType(args);
}
private static void printType (Object object){
Class type = object.getClass();
if (type.isArray()) {
Class elementType = type.getComponentType();
System.out.println("Array of: " + elementType);
System.out.println(" Length: " + Array.getLength(object));
}
}
}
注意:如果 printType() 用于前面定义的 buttons 和 components 变量调用,每个都会表明数组是 java.awt.Button 类型。如果不使用 isArray() 和 getComponentType() 方法,而且试图打印数组的 Class 类型,将获得一个包含 [ ,后面跟着一个字母和类名(如果是个基本数据类型就没有类名)的字符串。
例如,如果试图打印出上述 printType() 方法中的类型变量,将获得 class [Ljava.lang.String; 作为输出。
除了询问一个对象是不是数组以及是什么类型的数组之外,还可以在运行时用 java.lang.reflect.Array class 创建数组。这对于创建一般实用例程非常有用,这些例程执行数组任务,比如将大小加倍。(我们会立即回到那一点。)
要创建一个新数组,使用 Array 的 newInstance() 方法,它有两种变化形式。对于一维数组通常将使用较简单版本,它的执行方式如语句 new type [length] 所示,并作为对象返回数组: public static Object newInstance(Class type, int length) 。例如,下面的代码创建一个五个整数空间大小的数组:
int array[] = (int[])Array.newInstance(int.class, 5);
注意:要为基本数据类型指定 Class 对象,只要在基本数据类型名末尾添加 .class 就可以了。还可以使用包装类中的 TYPE 变量,如 Integer.TYPE。
newInstance() 方法中的第二种变化形式要求维数被指定为整型数组: public static Object newInstance(Class type,int dimensions []) 。在创建一个一维数组的最简单的情况下,将创建只有一个元素的数组。换句话说,如果要创建包含五个整数的相同数组,需要创建一个单个元素 5 的数组并传递到 newInstance() 方法,而不是传递整数值 5。
int dimensions[] = {5};
int array[] = (int[])Array.newInstance(int.class, dimensions);
在只需要创建一个矩形数组的时候,就可以将每个数组长度填充到这个 dimensions 数组中。例如,下面的代码与创建一个 3 X 4 的整数数组等价。
int dimensions[] = {3, 4};
int array[][] = (int[][])Array.newInstance(int.class, dimensions);
但是,如果需要创建一个非矩形数组,将需要多次调用 newInstance() 方法。第一次调用将定义外部数组的长度,并获得一个看上去很古怪的类参数([].class 适用于元素为 float 类型的数组)。每个后续调用将定义每个内部数组的长度。例如,下面演示了如何创建一个元素为 float 类型的数组,其内部数组的大小设置像一组保龄球瓶:第一排一个元素,第二排两个,第三排三个,第四排四个。为了将这种情况形象化,让我们回顾早先在图 2-4 展示的三角形数组。
float bowling[][] = (float[][])Array.newInstance(float[].class, 4);
for (int i=0; i<4; i++) {
bowling = (float[])Array.newInstance(float.class, i+1);
}
一旦在运行时创建了数组,还可以获取和设置数组元素。不过通常不会这样做,除非键盘上的方括号键失灵或者在动态的编程环境(程序被创建时数组名未知)中工作。 如表 2-2 所示, Array 类有一系列的 getter 和 setter 方法用来获取和设置数组元素。使用什么方法取决于处理的数组类型。表 2-2. 数组 getter 和 setter 方法
Getter 方法 Setter 方法
get(Object array, int index) set(Object array, int index, Object value)
getBoolean(Object array, int index) setBoolean(Object array, int index, boolean value)
getByte(Object array, int index) setByte(Object array, int index, byte value)
getChar(Object array, int index) setChar(Object array, int index, char value)
getDouble(Object array, int index) setDouble(Object array, int index, double value)
getFloat(Object array, int index) setFloat(Object array, int index, float value)
getInt(Object array, int index) setInt(Object array, int index, int value)
getLong(Object array, int index) setLong(Object array, int index, long value)
getShort(Object array, int index) setShort(Object array, int index, short value)
注意:可以一直使用 get() 和 set() 方法。如果数组是一个基本数据类型数组, get() 方法的返回值或 set() 方法的值参数将被包装到用于基本数据类型的包装类中,像装着一个 int 数组的 Integer 类那样。
================================================
什么时候需要使用单例设计?
单例模式:解决了一个类在内存中只能存在一个对象
使用单例模式总结就是以下三点:
(1)控制资源的使用,通过线程同步来控制资源的并发访问;
(2)控制实例产生的数量,达到节约资源的目的。
(3)作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信
比如:数据库连接池的设计一般采用单例模式,数据库连接是一种数据库资源