一、继承:

  1. java中只允许多层继承,不允许多重继承
  2. 继承的子类有时也称派生类,而被继承的类叫基类或父类(还有因为super关键字叫超类的)
  3. 子类是不能直接访问或调用父类中的私有成员的,但可以调用父类中的非私有方法
  4. 子类的实例化过程中,首先调用父类中的构造方法(默认)之后再调用子类自己的构造方法,因为在子类的构造方法中隐含了一个super()的语法
  5. super()调用的是父类的无参构造
  6. 3种访问权限:private<default<public
  7. 方法的覆写:被子类覆写的方法不能拥有比父类方法更加严格的访问权限(子类可以扩大权限,但是不能减小权限)
  8. 子类与父类声明了相同名称的属性,则在子类中直接访问的时候肯定是采用“就近原则”,即先找到本类种的属性,若是想调用父类的属性,则使用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();
	}

}
  1. 重载(Overloading):方法名称相同,但参数类型和个数不同————对权限没要求————发生在同一个类中
    覆写(Overriding):方法名称、参数类型、个数全部相同————被覆写的方法不能拥有更严格的权限————发生在继承类中
  2. super关键字:访问父类的属性、方法、构造
    this关键字:遵循“就近原则”,在访问属性、方法时,先在本类中查找,若没有,再在父类中查找
    【注】不论this或是super,调用构造方法时,必须放在子类构造方法的首行
  3. final关键字:final声明的类不能有子类
    final声明的方法不能被子类覆写,但在权限允许的情况下,可以被子类调用
    final声明的变量即成为常量,常量不可修改
    【注】final声明变量时,要求全部的字母大写,例如:public static final String INFO = "CHINA";,如果一个程序中的变量使用public static final声明时,此变量将称为全局常量

二、抽象类(abstract):

抽象类的作用类似于模板,用来规范子类的格式,但是并不能直接由抽象类创建对象,只能通过抽象类派生出的新的类,再由它来创建对象。抽象类中也存在单继承的局限

使用规则:
  1. 一个类中包含了抽象方法,那么这个类一定是抽象类(abstract class)
  2. 抽象类和抽象方法必须使用abstract关键字声明;
  3. 抽象方法只需要声明,不需要实现,如:public abstract void print();
  4. 抽象类必须被子类继承,子类必须覆写抽象类的全部抽象方法

三、接口(interface):

接口作为一种特殊的类,里面全是全局常量和公共的抽象方法所组成
【注】在接口中,抽象方法必须定义成public权限,并且方法默认也是public,而不是default,且一个类可实现多个接口

  1. 继承父类和实现接口的语法:
    class 子类 extends 抽象类 implements 接口A,接口B,...{}
  2. JDK1.8之后,就允许接口可以定义普通方法(使用default声明)与静态方法(用static声明):
    default void fun(){//代码}static void get(){//代码}

四、多态

面向对象的主要表现:方法的重载与覆写、对象的多态

  1. 类型:
    向上转型:子类对象 --> 父类对象 格式:父类 父类对象 = 子类实例 向下转型: 父类对象 --> 子类对象 格式:子类 子类对象 = (子类)父类实例 【注】对于向上转型,程序会自动完成,而对于向下转型,必须要指明转型的子类类型
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{
}
  1. A a1 = new B(); //通过向上转型实例化A类对象此时,a1是通过子类实例化的对象,所以a1同时是子类和父类的实例,所以可以直接进行向上或向下转型
  2. A a2 = new A(); //通过A类的构造实例化本类对象,这样直接使用了父类实例化本类对象,则一定不再是子类的实例了,所以不能进行转换a2 instanceof B == false
  3. 在进行对象的向下转型关系之前,最好先进行判断之后再进行相应的转换操作,这样可以避免转换异常的出现
if(a1 instanceof B){
    B b = (B)a1;//进行向下转型操作
}

【注】在类设计时,永远不要去继承一个已经实现好的类,只能继承抽象类或实现接口,因为一旦发生对象的向上转型后,所调用的方法一定是被子类所覆写过的方法

六、抽象类和接口的应用

  1. 抽象类的实际应用:模板设计
    抽象类中定义的一个抽象方法,让子类必须去覆写它,这就相当与一个模板,你必须得有这个内容,其他得东西相当于你的补充说明
  2. 接口得实际应用:制定标准
    1.接口是java解决多继承局限得一种手段
    2.接口作为一种标准,是要求要实现这个接口的子类,需要进行这些操作,而不关心该子类是干嘛的
    3.没有任何方法的接口都叫标识性接口,便于了解实现这个接口的类是用于干嘛的
  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()方法