- 基本概念
- 基本语法
- java基本数据类型
- java变量类型
- java运算符
- java循环语句:for, while 及 do…while
java条件语句:if…else- java switch case 语句
- Java Number & Math 类
- Java Character 类
- Java String 类
- Java StringBuffer 和 StringBuilder 类
- java数组
- java日期时间
- java正则表达式
- java方法
- Java 流(Stream)、文件(File)和IO
- Java Scanner 类
- next() 与 nextLine() 方法
- Java 异常处理
- java继承
- Java 重写(Override)与重载(Overload)
- java多态
- java抽象类
面向对象的语言
支持以下基本概念
基本语法
- 大小写敏感:Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的。
- 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
- 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
- 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。
- 主方法入口:所有的 Java 程序由 public static void main(String[] args) 方法开始执行。
编写java程序```java public static void main(String[] args)
修饰符 返回值类型 方法名(参数类型 参数名){ … 方法体 … return 返回值; } //void表示没有返回值

<a name="aemyB"></a>
#### 执行java程序
<br />具体实例
```html
import java.io.*;
public class EmployeeTest{
public static void main(String[] args){
/* 使用构造器创建两个对象 */
Employee empOne = new Employee("RUNOOB1");
Employee empTwo = new Employee("RUNOOB2");
// 调用这两个对象的成员方法
empOne.empAge(26);
empOne.empDesignation("高级程序员");
empOne.empSalary(1000);
empOne.printEmployee();
empTwo.empAge(21);
empTwo.empDesignation("菜鸟程序员");
empTwo.empSalary(500);
empTwo.printEmployee();
}
}
编译并运行
$ javac EmployeeTest.java
$ java EmployeeTest
源文件声明规则
- 一个源文件中只能有一个 public 类
- 一个源文件可以有多个非 public 类
- 源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为Employee.java。
- 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。
- 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面。
用java包对类进行分类
java基本数据类型
byte | 8位 | 0 |
---|---|---|
short | 16位 | 0 |
int | 32位 | 0 |
long | 64位 | 0L |
float | 32位 单精度 | 0.0f |
double | 64位 双精度 | 0.0d |
char | 16位 储存任何字符 | ‘u0000’ |
String (or any object) | 储存字符串 | null |
boolean | 布尔 | false |
容量小→容量大:自动类型转换,16可以自动转换位32,32可以自动转换位64
容量大→容量小:强制类型转换(转换数据类型必须兼容)
整数默认类型为int
小数默认类型为浮点型
java变量类型
在Java语言中,所有的变量在使用前必须声明
int a, b, c; // 声明三个int型整数:a、 b、c
int d = 3, e = 4, f = 5; // 声明三个整数并赋予初值
byte z = 22; // 声明并初始化 z
String s = "runoob"; // 声明并初始化字符串 s
double pi = 3.14159; // 声明了双精度浮点型变量 pi
char x = 'x'; // 声明变量 x 的值是字符 'x'
- 类变量(今天变量):独立于方法之外的变量,用 static 修饰。
- 类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。
- 实例变量:独立于方法之外的变量,不过没有 static 修饰。
局部变量:类的方法中的变量。
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 对所有类可见。使用对象:类、接口、变量、方法
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。 | 修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 | | —- | —- | —- | —- | —- | —- | | public | Y | Y | Y | Y | Y | | protected | Y | Y | Y | Y/N(说明) | N | | default | Y | Y | Y | N | N | | private | Y | N | N | N | N |
非访问修饰符
- static 修饰符,用来修饰类方法和类变量。
- final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。被 final 修饰的实例变量必须指定初始值。
- abstract 修饰符,用来创建抽象类和抽象方法。
- synchronized 和 volatile 修饰符,主要用于线程的编程。
抽象方法:可以没有实现的方法。
java运算符
操作符 | 描述 | 例子 |
---|---|---|
+ | 加法 - 相加运算符两侧的值 | A + B 等于 30 |
- | 减法 - 左操作数减去右操作数 | A – B 等于 -10 |
* | 乘法 - 相乘操作符两侧的值 | A * B等于200 |
/ | 除法 - 左操作数除以右操作数 | B / A等于2 |
% | 取余 - 左操作数除以右操作数的余数 | B%A等于0 |
++ | 自增: 操作数的值增加1 | B++ 或 ++B 等于 21(区别详见下文) |
— | 自减: 操作数的值减少1 | B— 或 —B 等于 19(区别详见下文) |
2B++先运算再自增,2++B先自增再运算
运算符 | 描述 | 例子 |
---|---|---|
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 | (A == B)为假。 |
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 | (A> B)为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 | (A <B)为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 | (A> = B)为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 | (A <= B)为真。 |
位运算符(二进制运算后转换为十进制)
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
| | 如果相对应位都是 0,则结果为 0,否则为 1 | (A | B)得到61,即 0011 1101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 | A << 2得到240,即 1111 0000 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 | A >> 2得到15即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 | A>>>2得到15即0000 1111 |
逻辑运算符
操作符 | 描述 | 例子 |
---|---|---|
&& | 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。(短路逻辑运算符:一个为false,后面不用执行) | (A && B)为假。 |
| | | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 | (A | | B)为真。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 | !(A && B)为真。 |
条件运算符(?:)
variable x = (expression) ? value if true : value if false
java循环语句:for, while 及 do…while
for, while 及 do…while
while( 布尔表达式 ) {
//循环内容
}
//布尔表达式为true则会一直循环下去
do {
//代码语句
}while(布尔表达式);
//布尔表达式为true则会一直循环下去,至少能够执行一次
for(初始化; 布尔表达式; 更新) {
//代码语句
}
java增强for循环
for(声明语句 : 表达式)
{
//代码句子
}
break 关键字
break;
continue 关键字
continue;
在 for 循环中,continue 语句使程序立即跳转到更新语句。
在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。
java条件语句:if…else
if(布尔表达式){
//如果布尔表达式的值为true
}else{
//如果布尔表达式的值为false
}
//多个条件
if(布尔表达式 1){
//如果布尔表达式 1的值为true执行代码
}else if(布尔表达式 2){
//如果布尔表达式 2的值为true执行代码
}else if(布尔表达式 3){
//如果布尔表达式 3的值为true执行代码
}else {
//如果以上布尔表达式都不为true执行代码
}
java switch case 语句
判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。
switch(expression){
case value :
//语句
break; //可选
case value :
//语句
break; //可选
//你可以有任意数量的case语句
default : //可选
//语句
}
当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。
如果 case 语句块中没有 break 语句时,匹配成功后,从当前 case 开始,后续所有 case (哪怕不匹配)的值都会输出,直到出现break或者跳出循环。
Java Number & Math 类
Java Number类
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。
包装类是把普通类型首字母大写,意思是把内置数据类型变为对象,方便使用
Java Math 类
public class Test {
public static void main (String []args)
{
System.out.println("90 度的正弦值:" + Math.sin(Math.PI/2));
System.out.println("0度的余弦值:" + Math.cos(0));
System.out.println("60度的正切值:" + Math.tan(Math.PI/3));
System.out.println("1的反正切值: " + Math.atan(1));
System.out.println("π/2的角度值:" + Math.toDegrees(Math.PI/2));
System.out.println(Math.PI);
}
}
Java Character 类
包装类是把普通类型首字母大写,意思是把内置数据类型变为对象,方便使用
Character ch = new Character('a');
转义序列
转义序列 | 描述 |
---|---|
\t | 在文中该处插入一个tab键 |
\b | 在文中该处插入一个后退键 |
\n | 在文中该处换行 |
\r | 在文中该处插入回车 |
\f | 在文中该处插入换页符 |
\‘ | 在文中该处插入单引号 |
\“ | 在文中该处插入双引号 |
\\ | 在文中该处插入反斜杠 |
Java String 类
创建之后无法修改,如果需要修改,则使用 StringBuffer & StringBuilder 类
String str = "Runoob";
String str2=new String("Runoob");
方法 | ||
---|---|---|
字符串长度 | string.length() | |
链接字符串 | string1.concat(string2); | 直接用+号比较多 |
创建格式化字符串 | printf() 和 format() |
Java StringBuffer 和 StringBuilder 类
StringBuilder sb = new StringBuilder(10);//创建了10个空位,要插入内容则往10个里面插入。
java数组
声明数组
dataType[] arrayRefVar; // 首选的方法
//实例
double[] myList;
创建数组
arrayRefVar = new dataType[arraySize];
声明和创建可以用一条语句完成
dataType[] arrayRefVar = new dataType[arraySize];
数组可以作为参数和返回值
//作为参数
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
//作为返回值
public static int[] reverse(int[] list) {
int[] result = new int[list.length];
for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
result[j] = list[i];
}
return result;
}
多维数组
为数组分配空间
type[][] typeName = new type[typeLength1][typeLength2];
String[][] str = new String[3][4];
String[][] s = new String[2][];
s[0] = new String[2];//定义几行
s[1] = new String[3];//定义几列
s[0][0] = new String("Good");//定义内容
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");
引用方式
num[1][0];
序号 | 方法 | 方法和说明 |
---|---|---|
1 | 搜索 | public static int binarySearch(Object[] a, Object key) 用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。 |
2 | 比较 | public static boolean equals(long[] a, long[] a2) 如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
3 | 赋值 | public static void fill(int[] a, int val) 将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
4 | 排序 | public static void sort(Object[] a) 对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
java日期时间
序号 | 方法 | 方法和描述 |
---|---|---|
1 | 比较两个日期 | boolean after(Date date) 若当调用此方法的Date对象在指定日期之后返回true,否则返回false。 |
2 | boolean before(Date date) 若当调用此方法的Date对象在指定日期之前返回true,否则返回false。 |
|
3 | int compareTo(Date date) 比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。 |
|
4 | Object clone( ) 返回此对象的副本。 |
|
5 | int compareTo(Object obj) 若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。 |
|
6 | boolean equals(Object date) 当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。 |
|
7 | long getTime( ) 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。 |
|
8 | int hashCode( ) 返回此对象的哈希码值。 |
|
9 | void setTime(long time) |
用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。 |
| 10 | 获取当前时间 | String toString( )
把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。 |
使用 SimpleDateFormat 格式化日期
SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
使用printf格式化日期
%t+字母
实例里面又在后面家里%n,不知道为什么
解析字符串为时间:parse()
没理解
Java 休眠(sleep)
Thread.sleep(1000*3)//毫秒为单位
Calendar类
set设置
c1.set(Calendar.YEAR,2008);
add设置
c1.add(Calendar.DATE, 10);//日期加上10,10天后
get设置
int year = c1.get(Calendar.YEAR);
java正则表达式
- Pattern 类
- Matcher 类
- PatternSyntaxException类
捕获组
通过左括号确定组
((A)(B(C)))
为以下四个组
((A)(B(C)))
(A)
(B(C))
(C)
语法
使用\双反斜杠匹配字符,比如\n匹配n
单反斜杠有特殊含义,比如\n匹配空格
字符 | 说明 |
---|---|
\ | 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如, n匹配字符 n。\n 匹配换行符。序列 \\\\ 匹配 \\ ,\\( 匹配 (。 |
^ | 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与”\n”或”\r”之后的位置匹配。 |
$ | 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与”\n”或”\r”之前的位置匹配。 |
* | 零次或多次匹配前面的字符或子表达式。例如,zo 匹配”z”和”zoo”。 等效于 {0,}。 |
+ | 一次或多次匹配前面的字符或子表达式。例如,”zo+”与”zo”和”zoo”匹配,但与”z”不匹配。+ 等效于 {1,}。 |
? | 零次或一次匹配前面的字符或子表达式。例如,”do(es)?”匹配”do”或”does”中的”do”。? 等效于 {0,1}。 |
{n} | n 是非负整数。正好匹配 n 次。例如,”o{2}”与”Bob”中的”o”不匹配,但与”food”中的两个”o”匹配。 |
{n,} | n 是非负整数。至少匹配 n 次。例如,”o{2,}”不匹配”Bob”中的”o”,而匹配”foooood”中的所有 o。”o{1,}”等效于”o+”。”o{0,}”等效于”o*”。 |
{n,m} | m 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。例如,”o{1,3}”匹配”fooooood”中的头三个 o。’o{0,1}’ 等效于 ‘o?’。注意:您不能将空格插入逗号和数字之间。 |
? | 当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是”非贪心的”。”非贪心的”模式匹配搜索到的、尽可能短的字符串,而默认的”贪心的”模式匹配搜索到的、尽可能长的字符串。例如,在字符串”oooo”中,”o+?”只匹配单个”o”,而”o+”匹配所有”o”。 |
. | 匹配除”\r\n”之外的任何单个字符。若要匹配包括”\r\n”在内的任意字符,请使用诸如”[\s\S]”之类的模式。 |
\n | 换行符匹配。等效于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等效于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。 |
Matcher 类
序号 | 方法及说明 |
---|---|
1 | public int start() 返回以前匹配的初始索引。 |
3 | public int end() 返回最后匹配字符之后的偏移量。 |
序号 | 方法及说明 |
---|---|
1 | public boolean lookingAt() 尝试将从区域开头开始的输入序列与该模式匹配。 |
4 | public boolean matches() 尝试将整个区域与模式匹配。 |
序号 | 方法及说明 |
---|---|
1 | public Matcher appendReplacement(StringBuffer sb, String replacement) 实现非终端添加和替换步骤。 |
2 | public StringBuffer appendTail(StringBuffer sb) 实现终端添加和替换步骤。 |
3 | public String replaceAll(String replacement) 替换模式与给定替换字符串相匹配的输入序列的每个子序列。 |
4 | public String replaceFirst(String replacement) 替换模式与给定替换字符串匹配的输入序列的第一个子序列。 |
java方法
命名规则
方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。
构造方法
每个类都有一个默认构造方法,一旦你定义了自己的构造方法,默认的构造方法就会失效。
- 没有返回值
- 大多数时候需要一个有参数的构造方法
- 构造函数首字母和后面单词的首字母
可变参数
一个方法只能制定一个,必须是方法最后一个参数。
制定参数类型后加一个省略号
typeName... parameterName
finalize() 方法
protected void finalize()
{
// 在这里终结代码
}
Java 流(Stream)、文件(File)和IO
没看懂
Java Scanner 类
next() 与 nextLine() 方法
next()遇到空白会将其截断
nextLine()可以获得空白,以enter为结束符
Java 异常处理
用户错误
程序错误
物理错误
多重捕获块
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}catch(异常类型3 异常的变量名3){
// 程序代码
}
throws/throw 关键字
finally关键字
- try的最末尾
- 无论是否发生异常,finally 代码块中的代码总会被执行。
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
java继承
继承格式
class 父类 {
}
class 子类 extends 父类 {
}
公共父类
public class Animal {
private String name;
private int id;
public Animal(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
以上为示例父类,以下为从父类继承的子类。(类似sketch的组件概念)
public class Penguin extends Animal {
public Penguin(String myName, int myid) {
super(myName, myid);
}
}
java不支持继承多个父类。但是可以多重,比如儿子再到孙子,也可以不同类继承同一父类。
- 子类拥有父类非 private 的属性、方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。(牵一发而动全身)
extends关键字
在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。implements关键字
使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。以下为示例 ```java public interface A { public void eat(); public void sleep(); }
public interface B { public void show(); }
public class C implements A,B { }
<a name="zo2HD"></a>
#### super 与 this 关键字
super访问父类成员<br />this访问子类成员
```java
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
final关键字
将类定义为不能继承的,不能被子类重写
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
构造器
super进行调用,有参数要求则传对应的参数,没有的话无需使用super进行调用,系统会自动调用
Java 重写(Override)与重载(Overload)
重写规则
- 参数列表与被重写方法的参数列表必须完全相同。
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
- 父类的成员方法只能被它的子类重写。
- 声明为 final 的方法不能被重写。
- 声明为 static 的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个类,则不能重写该类的方法。
重载
同一个方法为了应对各种不同参数的情况使用而建立的。
java多态
同一个行为具有多个不同表现形式或形态的能力
同一个事件发生在不同的对象上会产生不同的结果。
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
示例
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
虚函数
java中所有都是虚函数
java抽象类
不能实例化对象,其余的功能全部存在。父类不能使用自己的方法,只有子类能够使用。
使用 abstract class 来定义抽象类
抽象方法
抽象方法只包含一个方法名,而没有方法体。
抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。
public abstract double computePay();
声明抽象方法会造成以下两个结果:
- 如果一个类包含抽象方法,那么该类必须是抽象类。
- 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。