1.继承
继承的定义
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承单独的那个类即可.多个类可以称为子类,单独这个类称为父类或者超类.子类可以直接访问父类中的非私有的属性和行为.继承的出现提高了代码的复用性,让类与类之间产生了关系,提供了多态的前提。子类和父类之间应具所属(is a)关系,不应只为了获取其他类的某种功能而去继承。
通过 extends 关键字让类与类之间产生继承关系:class SubDemo extends Demo{}
继承的特点
a.Java只支持单继承,不支持多继承,即一个类只能有一个父类.
b.Java支持多层继承(继承体系)
函数的覆盖
当子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。在子类覆盖方法中,如果想继续使用被覆盖的父类方法可以通过super.函数名来实现。而且在覆盖时,子类方法权限一定要大于等于父类方法权限,静态只能覆盖静态。
函数的覆盖应注意的:父类的私有方法无法覆盖,方法名和参数列表必须相同
class Fu
{
void show()
{
System.out.println("父类的函数");
}
}
class Zi extends Fu
{
void show()
{
System.out.println("子类的函数");
}
}
问题:Overload和Override的区别?
答:Overload是重载,Override是覆盖
Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同.
Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现.
子类的实例化
当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数.子类中所有的构造函数默认都会访问父类中空参数的构造函数,因为每一个构造函数的第一行都有一条默认的语句super();子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的.
继承中构造代码块的特点
class Fu {
{
System.out.println("fu构造代码块");
}
static {
System.out.println("fu静态代码块");
}
}
class Zi extends Fu {
{
//super();每创建一次子类对象都调用一次父类的空构造
System.out.println("zi构造代码块");
}
Zi() {
System.out.println("zi构造函数");
}
}
class ExtendsDemo2 {
public static void main(String[] args) {
Zi z = new Zi();
Zi z1 = new Zi();
}
}
抽象类
Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类.
抽象类的特点:
a.抽象类和抽象方法必须用abstract关键字来修饰
b.抽象方法只有方法声明,没有方法体,定义在抽象类中
修饰符 abstract 返回值类型 函数名(参数列表) ;//后面没有{方法体},经常不注意就会加上{}
c.抽象类不可以被实例化,也就是不可以用new创建对象,是因为抽象类是从具体事务中抽取的,本身不是具体的,没有对应的实例。而且抽象类即使创建了对象,调用抽象方法也没有意义
d.抽象类可以通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类
注意:抽象类中可以有构造函数,也可以不定义抽象方法(图形化界面),abstract不能和final,private,static同时出现。
接口
接口的出现将“多继承”以另一种形式表现出来,即多实现,接口内部只有成员变量和成员方法,且格式是固定的子类必须全部覆盖接口中的所有抽象方法.
格式: interface {}
成员常量:public static final int PI=3.14;
成员变量:public abstract int x=5;
接口的特点:
a.接口是对外暴露的规则。
b.接口是程序的功能扩展。
c.接口可以用来多实现。
d.类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
e.接口与接口之间可以有继承关系。
接口与抽象类的区别:
A:抽象类只能被单继承;接口可以被多实现。
B:抽象类中的成员:
成员变量:可以是常量,也可以是变量。
成员方法:可以是抽象的,也可以是非抽象的。
构造方法:虽然不可以创建对象,但是可以给子类实例化用。
接口中的成员:
成员变量:只能是常量。默认修饰符 public static final
成员方法:只能是抽象的。默认修饰符 public abstract
C:抽象类中定义的是体系结构中的共性的内容。
接口中定义的是对象的扩展功能。
D:抽象类被继承表示的是:"is a"的关系。xx是yy中的一种。
接口被实现表示的是: "like a"的关系。xx像yy中的一种。
接口与接口之间的关系;接口与接口之间是继承关系;接口可以实现多继承
2.多态
多态是指父类或者接口的引用指向自己的子类对象,提高了程序的扩展性和后期可维护性。
多态实现的前提:要有继承或实现关系;要有覆盖操作
多态的特点:
成员变量:编译和运行都看父类
成员函数:静态的编译运行都看父类,非静态的编译看父类,运行看子类
注意:父类引用指向子类时,子类会被自动提升为父类类型,要使用子类特有的方法,需要进行强制类型转换
练习:
//动物都有吃的方法,但猫和狗在继承吃的方法的同时还有各自的功能,使用子类特有的方法,需要进行强制类型转换
abstract class Animal
{
public abstract void eat();//动物都有吃的方法
}
class Cat extends Animal
{
public void eat()
{
System.out.println("猫吃猫粮");
}
public void catchMouse()
{
System.out.println("猫在抓老鼠");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("狗吃骨头");
}
public void lookDoor()
{
System.out.println("狗在看门");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
function(new Cat());
function(new Dog());
}
public static void function(Animal a)
{
if(a instanceof Cat)//判断a是否是cat对象
{
Cat c =(Cat)a;
c.eat();
c.catchMouse();
}
else if(a instanceof Dog)
{
Dog d =(Dog)a;
d.eat();
d.lookDoor();
}
}
}