Java 面向对象核心-封装,继承,多态
封装
封装机制是面向对象的核心机制,在面向对象中通过封装机制实现的是类的抽象与定义。
继承
继承机制是面向对象的核心机制之一。在Java中继承所要实现的目的将重复的代码抽取到父类中,子类继承父类的属性方法,并扩展自己独有的属性和方法。Java支持的继承机制是单继承机制,就是一个子类只能拥有一个父类,通过extends关键字来实现继承。Java虽然是单继承机制。但是Java通过接口来弥补了这一缺陷。需要说明的是Java支持多重继承(A继承B,B继承C,A也就间接继承了C的属性和方法)。
继承的特性
子类只能继承父类的非私有的属性和方法。私有的属性和方法子类不能继承也无法访问使用。
Java支持单继承和多重继承
子类继承父类的非私有属性和方法后,可以进行重写和覆盖
子类继承父类的属性和方法时,不能继承父类的构造函数,访问父类的构造函数和属性需要通过下面的super关键字。
继承机制提高了代码之间的耦合度(这与高内聚低耦合的要求相反),降低了模块的独立性。
父类对象指向子类对象时,调用的属性和方法必须是父类拥有的,实际调用的方法和属性具体实现是子类的。
super关键字和this
super关键字是用来实现在子类中访问父类的属性和方法,代表引用当前的父类。
this关键字,用于代表本类的实例对象,只能在类内使用,用于访问本对象的属性和方法。类的静态方法只能访问静态成员(属性)。类的静态成员可以通过this关键字获取,但比应该这样做,因为静态属性和方法属于类的而不是属于单个对象。它在类加载时便初始化到方法区而非堆空间中。
继承实例
package com.stack.demo;
/**
* 抽象的动物类:抽象类不能实例化并且不能用final关键字修饰
* final 关键字修饰的类不能被继承。final关键字还被用来
* 修饰一些常量。字符串String就是final类
* 对公共代码进行抽取(一般也就是公共属性和方法)
* @author stack
*
*/
public abstract class Animal {
/**
* 动物属性
*/
public String id;
public String name;
public Animal() {
}
public Animal(String id,String name) {
this.id=id;
this.name=name;
}
/**
* 动物行为
*/
public abstract void eat();
public abstract void sleep();
}
package com.stack.demo;
public class Tiger extends Animal{
/**
* 扩展属性
*/
public String outLine;
public Tiger() {
}
public Tiger(String id,String name,String outLine) {
//调用父类的构造函数,父类的构造函数不能被继承
super(id, name);
this.outLine=outLine;
}
/**
* 继承的方法
* 这里用this关键字,是因为继承了属性
*/
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println(this.name+"吃饭");
}
@Override
public void sleep() {
// TODO Auto-generated method stub
System.out.println(this.name+"睡觉");
}
/**
* 扩展的方法
*/
public void introduction() {
System.out.println(this.id+" "+this.name+" "+this.outLine);
}
public static void main(String[] args) {
Tiger tiger=new Tiger("1","老虎","哺乳动物");
tiger.introduction();
tiger.eat();
tiger.sleep();
}
}
对抽象类的补充
抽象类用abstarct关键字来声明。
抽象类不能被实例化,抽象类的不能用final关键字来修饰。因为final关键字修饰的类代表最终类不能被继承。
抽象类中可以包含属性,抽象方法和实现的方法。
对接口的补充
接口中只能定义常量(static final关键字修饰的)和方法,默认访问属性是public的。
接口不能被实例化,是为了解决Java单继承局限而提出的。
接口中方法不能实现,需要有实现接口的类去覆盖方法。(JDK1.8可以通过在方法前用default关键字去修饰,通过default关键字修饰的方法可以在接口中实现,在实现类中直接调用。)默认情况下,我们认为接口的方法不能在接口中实现
抽象类与接口的比较
抽象类通过 abstarct class 关键字定义(extends关键字继承),接口通过 interfance关键字定义(implements关键字实例化)。
抽象类中可以包含普通属性,接口中只能包含常量(static final关键字)
抽象类中方法可以实例化,接口中的方法一般不实例化。接口的访问属性默认都为public
多态
多态分为方法多态和同一事件发生在不同对象会产生不同行为还有泛型多态。
方法多态
方法多态比较好理解,指的通过控制方法传递参数的多少和参数类型的不同来实现调用同一方法产生的处理逻辑不同,执行结果不同。
泛型多态
泛型多态指的是一个类中的属性方法不确定,可以通过泛型参数来实现动态绑定实例化对象的效果。
同一事件发生在不同对象会产生不同行为
同一事件发生在不同对象会产生不同行为这种情况下的多态体现在父类对象指向子类引用时,当执行某一方法时,实际上调用的是子类中的实现。
实例(在上面代码基础上改造)
package com.stack.demo;
/**
* @author stack
*
*/
public class Animal {
/**
* 动物属性
*/
public String id;
public String name;
public Animal() {
}
public Animal(String id,String name) {
this.id=id;
this.name=name;
}
/**
* 动物行为
*/
public void eat() {
};
public void sleep() {
};
}
package com.stack.demo;
public class Tiger extends Animal{
/**
* 扩展属性
*/
public String outLine;
public Tiger() {
super("1","老虎");
this.outLine="哺乳类";
}
/**
* 继承的方法
* 这里用this关键字,是因为继承了属性
*/
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println(this.name+"吃饭");
}
@Override
public void sleep() {
// TODO Auto-generated method stub
System.out.println(this.name+"睡觉");
}
/**
* 扩展的方法
*/
public void introduction() {
System.out.println(this.id+" "+this.name+" "+this.outLine);
}
}
package com.stack.demo;
public class Lion extends Animal{
/**
* 扩展属性
*/
public String outLine;
public Lion() {
super("1","狮子");
this.outLine="哺乳类";
}
/**
* 继承的方法
* 这里用this关键字,是因为继承了属性
*/
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println(this.name+"吃饭");
}
@Override
public void sleep() {
// TODO Auto-generated method stub
System.out.println(this.name+"睡觉");
}
/**
* 扩展的方法
*/
public void introduction() {
System.out.println(this.id+" "+this.name+" "+this.outLine);
}
}
package com.stack.demo;
public class AninalAdmin {
public static void eat(Animal animal) {
animal.eat();
}
public static void sleep(Animal animal) {
animal.sleep();
}
public static void main(String[] args) {
Animal tiger=new Tiger();
Animal lion=new Lion();
/**
* 通过同一方法传递一个父类引用子类来达到产生不同的效果。
*/
AninalAdmin.eat(tiger);
AninalAdmin.eat(lion);
AninalAdmin.sleep(tiger);
AninalAdmin.sleep(lion);
}
}
总结
面向对象的三大核心机制封装,继承,多态,知识点比较细,要重在理解。