1.类的继承格式
class 父类{}
class 子类 extends 父类{}
java只允许单继承,不允许多重继承,但可以多层继承,如下图,
示例代码如下,
package java_book;
public class testExtends {
public static void main(String[] args) {
Student s = new Student();
s.setName("张三"); // name属性是私有的,可以使用getter() setter()方法处理,作用范围为当前实例内部
Student.age = 30; // age属性是公有的,通过类来直接赋值,所有该类的实例对象的此属性都会改变
// 同时注意,子类不能直接调用父类的私有成员,如s.name="张";这样会报错
System.out.println("姓名:" + s.getName() + ",年龄:" + s.getAge());
Student s2 = new Student();
System.out.println("姓名:" + s2.getName() + ",年龄:" + s2.getAge());
}
}
class Person2{
private String name;
public static int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Student extends Person2{
}
运行结果如下,
姓名:张三,年龄:30
姓名:null,年龄:30
2.子类对象的实例化过程
在继承的操作中,对于子类对象的实例化也是有要求的,即子类对象实例化之前必须首先调用父类中的构造方法后再调用子类自己的构造方法,如下图,
3.方法的覆写
当子类定义了与父类相同的方法名称时,会出现方法的覆写。
使用方法的覆写时,必须考虑到权限,即被子类覆写的方法不能比父类方法更加严格的访问权限,否则程序编译时会报错。
访问权限大小关系:private < default < public
在子类中调用父类的方法用super关键字,调用自己的方法用this关键字。
4.属性的覆写
类似方法的覆写,如果出现属性的覆写,在子类中可以用super.name调出父类的name属性,使用this.name调出子类自己的name属性。
5.super关键字
使用super关键字可以从子类中调用父类中的构造方法、普通方法和属性,如果是调用构造方法,与this调用构造方法的要求一样,语句必须放在子类构造方法的首行。
6.final关键字
final表示最终,也可以称为完结器。
可以使用final声明类、属性、方法,需要注意以下三点,
1)使用final声明的类不能有子类,即不能被继承;
2)使用final声明的方法不能被子类所覆写;
3)使用final声明的变量即称为常量,常量不可以修改(final声明变量时,变量名全部大写)。
7.抽象类
在java中也可以创建一种类专门用来当作父类,这种类称为抽象类。
抽象类的作用类似模板,其目的是要设计者依据它的格式来修改并创建新的类,但是并不能直接由抽象类创建对象,只能通过抽象类派生出新的类,再由它来创建对象。
抽象类的使用规则有以下四点,
1)包含一个抽象方法的类必须是抽象类;
2)抽象类和抽象方法都要使用abstract关键字声明;
3)抽象方法只需声明而不需要实现;
4)抽象类必须被子类继承,子类(如果不是抽象类)必须覆写抽象类中的全部抽象方法。
抽象类的定义格式,
abstract class 抽象名称{
属性;
访问权限 返回值类型 方法名称(数据类型 参数, ...){ // 普通方法
[return 返回值;]
}
访问权限 abstract 返回值类型 方法名称(数据类型 参数, ...){ // 抽象方法
//抽象方法中没有方法体;
}
}
注意:一个抽象类不能使用final关键字声明,因为它需要被继承。
注意:在子类对象实例化前,会默认调用父类中的无参构造(即子类构造方法中的第一行,默认含有super())。
个人对抽象类的理解,对类名、方法名的规范。
8.接口
接口是java中最重要的概念之一,它可以被理解为一种特殊的类,是由全局常量和公共的抽象方法(必须是public访问权限)组成。
接口的定义格式,
interface 接口名称{
全局常量;
抽象方法; // 必须是public访问权限,一般可以省略,但不代表它是default权限
}
与抽象类一样,接口若要使用,也必须通过子类,子类通过implements关键字实现接口,格式如下,
class 子类名称 implements 接口1,接口2, ...{
}
由上述接口使用格式可以看出,一个子类可以使用多个接口,这实际上摆脱了java的单继承局限。
如果一个子类既继承抽象类又继承接口,写法如下,
class 子类名称 extends 抽象类名称 implements 接口1, 接口2, ...{
}
java中,接口不允许继承抽象类,但可以继承多个接口,写法如下,
interface 接口名称 extends 接口1,接口2, ...{
}
9.多态性
多态性在面向对象中是一个最重要的概念,主要有两个表现形式,
1)方法的重载和覆写(上文已进行过详细描述)
2)对象的多态性
对象的多态性主要有两种类型,
1)向上转型,子类对象 -> 父类对象
2)向下转型,父类对象 -> 子类对象
对于向上转型,程序会自动完成,而对于向下转型,必须明确地指明要转型的子类类型。
对于向上转型,格式为:父类 父类对象 = 子类实例;举例如下,
父类A,子类B继承父类A,
B b = new B();
A a = b;
a.fun(); // 如果子类B中覆写了方法fun(),此时调用的是B中的方法。但a实例不能调用A中没有B中有的方法。
对于向下转型,格式为:子类 子类对象 = (子类)父类实例;
父类A,子类B继承父类A
A a = new B();
B b = (B)a;
b.fun3(); // 如果子类B中覆写了方法fun3(),此时调用的是B中的方法。
// b实例可以调用子类B中自己的方法,这点与向上转型不同
10.instanceof关键字
可以使用instanceof关键字判断一个对象是否是某个类的实例,格式如下,
对象 instanceof 类 --> 返回boolean类型
11.Object类
所有的类都有一个公共的父类Object,一个类只要没有明显地继承一个类,则肯定是Object的子类,
这里的两行代码含义一样
class Person extends Object{}
class Person{}
Object的作用是,提供了很多方法,如下图,
12.包装类
包装类的作用:将八种基本数据类型变为一个类的形式,得出八种包装类,它们都是Number的子类。
将一个基本数据类型变为包装类,这样的过程称为装箱操作,而将一个包装类变为基本数据类型的过程称为拆箱操作。
示例如下,
int x = 30; // 声明一个基本数据类型
Integer i = new Integer(x); // 装箱:将一个基本数据类型变为包装类
int temp = i.intValue(); // 拆箱:将一个包装类变为基本数据类型
本章小结