继承性
类所描述过的属性及行为,即已定义的变量和方法,在继承产生的类中完全可以使用。被继承的类称为父类或超类,而经继承产生的类称为子类或派生类。若一个子类只允许继承一个父类,称为单继承;
好处:
- 面向对象程序设计中的继承机制,大大增强了程序代码的可复用性,提高了软件的开发效率,降低了程序产生错误的可能性,也为程序的修改扩充提供了便利。
- 功能的扩展
- 多态的使用
格式:class A exends B{}
public class Person {
String name;
Integer age;
public void eat(){
System.out.println("我在吃饭");
}
public void sleep(){
System.out.println("我在睡觉");
}
}
public class Student extends Person{
}
public class ExtendsTest {
public static void main(String[] args) {
Student student=new Student();
student.eat();
student.sleep();
}
}
说明:一旦A继承了B,A类就继承了B的所有属性和方法,包括私有方法。
子类可以定义自己特有的方法,实现功能的扩展
子类和父类的关系:扩展的关系
继承的规定
- Java只能单继承和多层继承
- 单继承:一个类只能有一个子类
- 子类的相对的,子类直接继承父类:直接父类。间接继承叫做间接父类。子类继承后,活动父类和间接父类的所有方法和属性
方法的重写
定义:子类可以根据父类继承的方法,后对同名童参数进行改造。程序执行是时候,子类的方法将覆盖父类的方法。
应用
重写以后,通过子类对象调用子父类同名同参数的方法,实际上执行的是子类重写父类的方法
class Person {
String name;
Integer age;
public void eat(){
System.out.println("人在吃饭");
}
}
class Student extends Person{
//科目
String major;
//重写的方法
public void eat(){
System.out.println("学生在睡觉");
}
}
public class OverwriteTest {
public static void main(String[] args) {
Student student=new Student();
student.eat();
}
}
结果
学生在睡觉
重写的规定
方法的声明格式:
格式:class A exends B{}
子类中的方法叫做重写方法,父类的叫被重写方法
- 重写的时候,两者的方法名 形参列表相同
- 子类重写的方法修饰符要大于或等于父类
特殊情况:子类不能重写父类的私有方法 - 返回值类型:
3.1 父类是void,子类是void
3.2 父类返回是A类型,子类可以是A类或者A的子类 - 子类抛出的异常小于获等于父类重写的方法的异常
注意:
子类和父类同名同参数的方法为非static是为重写,反之不是。static是属于类的,子类无法覆盖父类的方法
super关键字
当需要在子类中调用父类的被重写方法时,要使用 super 关键字。
修饰:属性 方法构造器
使用:
- 在子类方法或者构造器中,使用super.属性或者super.方法,显式调用父类中的属性或者方法
class Person {
String name;
Integer age;
public void eat(){
System.out.println("人在吃饭");
}
}
class Student extends Person{
//科目
String major;
//重写的方法
@Override
public void eat(){
super.eat();
System.out.println("学生在吃饭");
}
public class OverwriteTest {
public static void main(String[] args) {
Student student=new Student();
student.eat();
}
}
结果
人在吃饭
学生在吃饭
调用构造器的问题
class Person {
String name;
Integer age;
public Person(String name, Integer age) {
System.out.println("Person的构造方法");
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("人在吃饭");
}
}
class Student extends Person{
//科目
String major;
//构造方法
public Student(String name, Integer age, String major) {
//调用父类分构造方法
super(name, age);
this.major = major;
}
public String show() {
return "Student{" +
"name='" + this.name + '\'' +
", age=" + this.age +
", major='" + this.major + '\'' +
'}';
}
public class OverwriteTest {
public static void main(String[] args) {
Student student=new Student("张三",18,"Java");
System.out.println(student.show());
}
}
Person的构造方法
Student{name='张三', age=18, major='Java'}
说明:
- super(形参列表)的使用,必须声明在子类构造的首行
- 在构造器的首行,没有显示声明this或者super,默认的调用父类的空惨构造器。
子类实例化的过程
从结果来看,子类继承父类,获取父类的属性和方法。当new 子类的时候,在堆空间会加载父类所有的声明属性
从过程来看,当new子类的时候,会直接或简介调用父类的构造器,进而调用父类分父类的构造器指导Object类的空参位置。因为加载父类的结构,所以才会有父类的结构,子类对象才可以调用
多态性
含义
多态是面向对象程序设计的又一个重要特征。多态是指允许程序中出现重名现象。Java语言中含有方法重载与对象多态两种形式的多态。
方法重载:在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。
对象多态:子类对象可以与父类对象进行相互转换,而且根据其使用的子类不同完成的功能也不同。
本质上就是父类的引用指向子类对象
应用
public class PolymorphismTest {
public static void main(String[] args) {
//多态性:父类引用指向子类对象
Animal animal=new Dog();
//多态的使用
animal.eat();
animal.shout();
}
}
class Animal{
public void eat(){
System.out.println("Animal.eat");
}
public void shout(){
System.out.println("Animal.shout");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void shout(){
System.out.println("汪汪汪");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void shout(){
System.out.println("喵喵喵");
}
public void tree(){
System.out.println("Cat.tree");
}
}
说明:
虚拟方法调用:编译期间,我们只能调用父类声明的方法,运行期间,我们实际上执行的子类重写父类的方法。总结:编译看左边,运行看右边
多态前提:类继承关系,方法的重写
多态性的用处只是适用于方法,不适用于属性
向下转型
使用()来强转,来调用子类特有的方法;
续上面代码
public class PolymorphismTest {
public static void main(String[] args) {
//多态性:父类引用指向子类对象
Animal animal=new Cat();
//强制转化
Cat cat=(Cat) animal;
cat.tree();
}
}
注意:
可能出现异常,可以使用instanceof使用来判断对象两边是否相等
Object类的使用
所有类的根父类
未使用extends指明父类,则父类为java.lang.Object类
包装类(Wrapper)
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。
包装类 基本数据类型
Boolean boolean
Byte byte
Short short
Integer int
Long long
Character char
Float float
Double double
转换
关键字static
不同对象共享相同属性,可以使用static来修饰。例如我们都是中国人,国籍是中国。国籍就是我们共享的对象
可以修饰属性,方法,代码块,
应用:
内部类不管有多少个对象,都使用同一个static属性;使用static方法可以避免实例化对象调用方法的限制。
修饰属性
静态变量:创建类的多个对象,多个对象共享同一个静态变量,当通过一个对象修改一个静态属性时候,会导致其他对象调用这个静态变量是时候,是修改过的。
public class StaticTest {
public static void main(String[] args) {
Chinese chinese1=new Chinese("zhangsan",20);
//赋值给属性
chinese1.nation="China";
Chinese chinese2=new Chinese("lisi",50);
System.out.println(chinese2.nation);
//输出China
}
}
class Chinese{
String name;
int age;
//静态变量
static String nation;
public Chinese(String name,int age){
this.age=age;
this.name=name;
}
}
说明:静态变量随着类的加载而加载,早于对象的创建。由于类只加载一次,静态变量也会加载一次,存在方法区的静态域。
内存解析:
修饰方法
通过类名.方法来调用,随着类的加载而加载
public class StaticTest {
public static void main(String[] args) {
Chinese.show();
}
}
class Chinese{
String name;
int age;
//静态变量
static String nation;
//静态方法
public static void show(){
System.out.println("我是中国人");
}
}
注意:在static中,不能用super,this
应用-单例模式
对于某个类只能存在一个对象实例,并且类的只提供一个取得其类的对象的实例方法
mian方法的使用
代码块
使用{}来学生
作用:用来初始化类和对象,只能用static来修饰
抽象类和抽象方法
将一个父类设计的非常抽象,以至于他没有具体的实例,这样子的类叫抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
public class AbstractTest {
public static void main(String[] args) {
Student student = new Student();
student.run();
}
}
abstract class Peson{
String name;
public Peson() {
System.out.println("抽象类");
}
/**抽象方法 只有方法的声明,没有方法体*/
public abstract void run();
}
class Student extends Peson{
public Student() {
System.out.println("子类");
}
/**重写父类的方法*/
@Override
public void run() {
System.out.println("学生在跑");
}
}
说明:
- 抽象类不能实例化,一定有构造器。开发中通常提供抽象类的子类,让子类实例化
- 抽象方法只有方法的声明,没有方法体。包含抽象方法一定是抽象类,反之不然。若子类重写父类的所有的抽象方法,才能实例化。没有的话,子类又是一个抽象类
抽象类和接口的区别:
相同点:不能被实例化,都可以被继承
不同的:抽象类有构造器;接口不能声明构造器
多继承和单继承。