一、继承:
- java中只允许多层继承,不允许多重继承
- 继承的子类有时也称派生类,而被继承的类叫基类或父类(还有因为super关键字叫超类的)
- 子类是不能直接访问或调用父类中的私有成员的,但可以调用父类中的非私有方法
- 子类的实例化过程中,首先调用父类中的构造方法(默认)之后再调用子类自己的构造方法,因为在子类的构造方法中隐含了一个super()的语法
- super()调用的是父类的无参构造
- 3种访问权限:private<default<public
- 方法的覆写:被子类覆写的方法不能拥有比父类方法更加严格的访问权限(子类可以扩大权限,但是不能减小权限)
- 子类与父类声明了相同名称的属性,则在子类中直接访问的时候肯定是采用“就近原则”,即先找到本类种的属性,若是想调用父类的属性,则使用super调用
import java.util.jar.Attributes.Name;
class Person{
private String name = "人";
private 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;
}
public void print() {
System.out.println("Person -> print(); ");
}
}
class Student extends Person{
private String name = "学生";
@Override
public void print() {
System.out.println("Student -> print(),名字"+super.getName());
//因为name属性在父类中为private,所以不能被子类调用或访问,只用通过public权限的getName()方法去访问
//System.out.println("Student -> print(),名字"+super.name());
}
}
public class OverrideDemo05 {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Student().print();
}
}
- 重载(Overloading):方法名称相同,但参数类型和个数不同————对权限没要求————发生在同一个类中
覆写(Overriding):方法名称、参数类型、个数全部相同————被覆写的方法不能拥有更严格的权限————发生在继承类中 - super关键字:访问父类的属性、方法、构造
this关键字:遵循“就近原则”,在访问属性、方法时,先在本类中查找,若没有,再在父类中查找
【注】不论this或是super,调用构造方法时,必须放在子类构造方法的首行 - final关键字:final声明的类不能有子类
final声明的方法不能被子类覆写,但在权限允许的情况下,可以被子类调用
final声明的变量即成为常量,常量不可修改
【注】final声明变量时,要求全部的字母大写,例如:public static final String INFO = "CHINA";
,如果一个程序中的变量使用public static final
声明时,此变量将称为全局常量
二、抽象类(abstract):
抽象类的作用类似于模板,用来规范子类的格式,但是并不能直接由抽象类创建对象,只能通过抽象类派生出的新的类,再由它来创建对象。抽象类中也存在单继承的局限
使用规则:
- 一个类中包含了抽象方法,那么这个类一定是抽象类(
abstract class
) - 抽象类和抽象方法必须使用abstract关键字声明;
- 抽象方法只需要声明,不需要实现,如:
public abstract void print();
- 抽象类必须被子类继承,子类必须覆写抽象类的全部抽象方法
三、接口(interface):
接口作为一种特殊的类,里面全是
全局常量和公共的抽象方法所组成
【注】在接口中,抽象方法必须定义成public权限,并且方法默认也是public,而不是default,且一个类可实现多个接口
- 继承父类和实现接口的语法:
class 子类 extends 抽象类 implements 接口A,接口B,...{}
- JDK1.8之后,就允许接口可以定义普通方法(使用default声明)与静态方法(用static声明):
default void fun(){//代码}
static void get(){//代码}
四、多态
面向对象的主要表现:方法的重载与覆写、对象的多态
- 类型:
向上转型:子类对象 --> 父类对象 格式:父类 父类对象 = 子类实例
向下转型: 父类对象 --> 子类对象 格式:子类 子类对象 = (子类)父类实例
【注】对于向上转型,程序会自动完成,而对于向下转型,必须要指明转型的子类类型
class A{
public void fun1() {
System.out.println("A ---> fun()1");
}
public void fun2() {
// System.out.println("A ---> fun2()");
this.fun1();
}
}
class B extends A{
@Override
public void fun1() {
System.out.println("B ---> fun1()");
}
public void fun3() {
System.out.println("B ---> fun3()");
}
}
public class PolDemo02 {
public static void main(String[] args) {
A a = new B();//向上转型 new B()为匿名对象
//虽然是使用父类对象调用的fun1(),但实际上调用的方法是被子类覆写过的方法
//即:如果对象发生了向上转型关系,所调用的方法肯定是被子类覆写过的方法
a.fun1();
//此时,父类对象通过this.fun1()也是调用的被子类覆写过的fun1()方法
a.fun2();
//此时对象a是无法调用子类B中的fun3()方法,因为fun3()只是子类的的方法
//若要调用fun3(),必须使用B的对象
//结论:当发生向上转型之后,父类对象所调用的方法是被子类覆写过的方法,若子类没有覆写,则调用的是自己原来的方法
B b = (B)a; //向下转型
b.fun1();//调用被自己类覆写的方法
b.fun2();//因为没覆写,调用父类的fun2()方法
b.fun3();//调用自己才有的fun3()方法
}
}
【注】
1.对象在向下转型之前,必须首先发生对象向上转型。否则将会出现对象转换异常
2.一旦发生对象的向上转型之后,调用的方法肯定是被子类覆写过的方法
五、instanceof
//父类
class A{
}
//子类B继承父类A
class B extends A{
}
-
A a1 = new B(); //通过向上转型实例化A类对象
此时,a1
是通过子类实例化的对象,所以a1
同时是子类和父类的实例,所以可以直接进行向上或向下转型 -
A a2 = new A(); //通过A类的构造实例化本类对象
,这样直接使用了父类实例化本类对象,则一定不再是子类的实例了,所以不能进行转换a2 instanceof B == false
- 在进行对象的向下转型关系之前,最好先进行判断之后再进行相应的转换操作,这样可以避免转换异常的出现
if(a1 instanceof B){
B b = (B)a1;//进行向下转型操作
}
【注】在类设计时,永远不要去继承一个已经实现好的类,只能继承抽象类或实现接口,因为一旦发生对象的向上转型后,所调用的方法一定是被子类所覆写过的方法
六、抽象类和接口的应用
- 抽象类的实际应用:模板设计
抽象类中定义的一个抽象方法,让子类必须去覆写它,这就相当与一个模板,你必须得有这个内容,其他得东西相当于你的补充说明 - 接口得实际应用:制定标准
1.接口是java解决多继承局限得一种手段
2.接口作为一种标准,是要求要实现这个接口的子类,需要进行这些操作,而不关心该子类是干嘛的
3.没有任何方法的接口都叫标识性接口
,便于了解实现这个接口的类是用于干嘛的 - 设计模式:
A:适配器设计:一个类要实现一个接口,但又使用不完接口中的全部方法,所以需要一个Adapter(抽象类实现)去实现这个接口,再覆写这个接口中的方法,最后,子类就可以选择性的去覆写接口中的方法,否则,子类需要将接口中的方法全部实现
B:工厂设计
class Factory{
public static Fruit getInstance(String className){
Fruit f = null;
if("apple".equals(className)){
f = new Apple();
}
}
}
class main(){
Fruit f = null;//定义接口对象
f = Factory.getInstance("apple");//通过工厂去实例化对象
f.eat();
}
【注】接口也能声明对象,但不可对其进行实例化,但可以让实现这个接口的子类去实例化这个对象
Object类
对于一个设计良好的类来说,最好覆写Object类中的equals()、hashCode()、toString()方法
网友评论