继承:父类对象空间优于子类对象产生。子类对象中包含了其对应父类对象空间,便可以包含其父类对象成员,如果父类成员非private修饰,那么子类可以随意使用父类成员。子类的构造方法调用时一定先调用父类的构造方法。
抽象类无法创建对象,只能被子类继承后,创建子类对象。子类需要继承父类并完成最终的方法实现细节(即重写方法,完成方法体)。而此时,方法重写不再是加强父类方法功能,而是父类没有具体实现,子类完成了具体实现,我们将这种方法重写叫做实现方法。
抽象类是拥有构造方法的,其存在的意义在于对自身进行初始化,供其子类使用。
接口:接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的“类”。
接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定义与实现分离,优化了程序设计。
一切事物均有功能,即一切事物均有接口 。
接口的定义:与定义类的class不同,接口定义时需要使用interface关键字。
定义接口所在的仍为.java文件,虽然声明时使用的为interface关键字的编译后仍然会产生.class文件。这点可以让我们将接口看做是一种只包含了功能声明的特殊类。
定义格式:
public interface 接口名{
抽象方法1;
抽象方法2;
抽象方法3;
}
使用interface代替了原来的class,其他步骤与定义类相同:
接口中的方法均为公共访问的抽象方法
接口中无法定义普通的成员变量
类实现接口:
类与接口的关系为实现关系,即类实现接口。实现的动作类似继承,只是关键字不同,实现使用implements.其它类(实现类)实现接口后,就相当于声明:“我应该具备这个接口中的功能”。实现类仍然需要重写方法以实现具体的功能。
格式:
class 类implements 接口 {
重写接口中方法
}
在类实现接口后,该类就会将接口中的抽象方法继承过来,此时该类需要重写该抽象方法,完成具体的逻辑。
接口中定义功能,当需要具有该功能时,可以让类实现该接口,只声明了应该具备该方法,是功能的声明。
在具体实现类中重写方法,实现功能,是方法的具体实现。
于是,通过以上两个动作将功能的声明与实现便分开了。(此时请重新思考:类是现实事物的描述,接口是功能的集合。)
1、接口中可以定义变量,但是变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称之为常量,其值不能改变。
2、接口中可以定义方法,方法也有固定的修饰符,public abstract
3、接口不可以创建对象。
4、子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。
interface Demo { ///定义一个名称为Demo的接口。
publicstatic final int NUM = 3;// NUM的值不能改变
publicabstract void show1();
publicabstract void show2();
}
//定义子类去覆盖接口中的方法。类与接口之间的关系是 实现。通过关键字 implements
class DemoImpl implementsDemo { //子类实现Demo接口。
//重写接口中的方法。
publicvoid show1(){}
publicvoid show2(){}
}
接口的特点:
1.接口可以继承接口
如同类继承后便拥有了父类的成员,可以使用父类的非私有成员。A接口继承B接口后,A接口拥有了A,B两个接口中所有的抽象方法。
2.java支持一个类同时实现多个接口,或一个接口同时继承多个接口
接口和抽象类的区别:
相同点:
1.都位于继承的顶端,用于被其它类实现或继承
2.都不能直接实例化对象
3.都包含抽象方法,其子类都必须覆写这些抽象方法
区别:
1.抽象类为部分方法提供实现,避免子类重复实现这些方法,提高代码重用性;接口只能包含抽象方法;
2.一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了java的单继承)
3.抽象类为继承体系中的共性内容,接口为继承体系中的扩展功能。
二者的选用:
优先选用接口,尽量少用抽象类;
需要定义子类的行为,又要为子类提供共性功能时才选用抽象类。
接口如果是abstract,那么这个抽象接口里的方法可以是抽象的也可以不是抽象的。
类如果是抽象的,那么这个类里面的方法可以是抽象的,也可以不是抽象的(注意:抽象类的抽象方法没有方法体,抽象类的普通方法有方法体)。如果类不是抽象的,那么方法不可以有抽象的
public abstract class {
public void a(){};
public abstract void b();
}
类与类:继承关系,一个类只能继承一个类,父类中的方法子类可以不用完全继承。
类与接口之间:实现关系,一个类可以实现多个接口。
接口与接口:继承关系,一个接口可以继承多个接口。
多态:是继封装、继承之后,面向对象的第三大特性。
子类对象表现的是父类的形式,在调用方法时调用的是子类重写父类的方法,但是不能调用子类特有的方法。
现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。
java作为面向对象的语言,同样可以描述一个事物的多种形态,如student类继承了person类,一个student的对象便是student,又是person。
Java中多态的代码体现在一个子类对象(实现类对象)既可以给这个子类(实现类对象)引用变量赋值,又可以给这个子类(实现类对象)的父类(接口)变量赋值。
如Student类可以为Person类的子类。那么一个Student对象既可以赋值给一个Student类型的引用,也可以赋值给一个Person类型的引用。
最终多态体现为父类引用变量可以指向子类对象。
多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。
在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。
多态的代码体现:
Java中多态的代码体现在一个子类对象(实现类对象)既可以给这个子类(实现类对象)引用变量赋值,又可以给这个子类(实现类对象)的父类(接口)变量赋值。
如Student类可以为Person类的子类。那么一个Student对象既可以赋值给一个Student类型的引用,也可以赋值给一个Person类型的引用。
最终多态体现为父类引用变量可以指向子类对象。
多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。
在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。
具体格式如下:
父类引用指向子类对象就是多态的定义格式。同一个父类的方法会被不同的子类重写为各自的具体实现。在调用方法时,调用的为各个子类重写后的方法。
父类类型 变量名 = new 子类类型();
变量名.方法名();
此时,虽然该变量指向的是子类对象,但表现为一个父类的形态,可以调用一切父类的方法,子类特有的方法将不能调用。
多态的好处和弊端:
当变量名指向不同的子类对象时,由于每个子类对象重写父类方法的内容不同,所以会调用不同的方法。
优点:配合继承与方法重写提高了代码的复用性与扩展性,如果没有方法重写,则多态没有意义。
缺点:不能调用子类特有的方法。
例如:
//定义父类
public class Person {
public static void Aa() {
System.out.println("fulei");
}
}
//定义子类
public class Chinese extends Person {
public static void Ba() {
System.out.println("zilei");
}
}
public class Test03 {
public static void main(String[] args) {
Person c = new Chinese();
c.Aa();//c对象表现的是父类的形态,只能调用父类的方法,子类的方法就不能调用。
}
}
多态向上向下类型转换:
多态本来就是子类类型向父类类型向上转型的过程。多态的转型分为向上转型和向下转型。
向上转型:子类对象赋值给一个父类引用时。
格式:父类类型 变量名=new 子类类型();
Animal p=new Cat();
向下转型:
子类类型 变量名=(子类类型)父类类型的变量;
Cat c=(Cat)a;
instanceof关键字:
使用格式:boolean a=引用变量 instanceof 类;
if(a instanceof Cat){
Cat c=(Cat)a;
}
内部类:
首先我们要知道什么是内部类:就是将类写在其他类的内部。可以写在其他类的成员位置和局部位置,这时写在其它类内部的就叫做内部类,其它类称为外部类。
什么时候使用:在描述某一个事物时,一个类的内部还包括其它事物,
内部类分为成员内部类和局部内部类,在内部类中可以直接访问外部类的所有成员