Java面向对象的三大特征
一、Java面向对象的特征之封装
1、封装的概念
面向对象是利用对象来代表现实生活中的事物。使用对象的属性来表示事物的特性;使用对象中的方法代表事物的行为亦成为动作。将事物的属性和方法封存到一起形成对象的过程就是对象的封装。
封装一方面将属性和方法放置到一起形成对象,另一方面也要控制这些方法和属性的访问权限。
作用:封装提高代码的复用性,降低了代码的冗余度,保证数据的合法性。
2、访问权限控制符及访问控制权限
3.访问权限控制符的使用
- 可以用在成员属性上
- 可以用在成员方法上
- 可以用在类、接口上:当用于修饰类和接口时,只能是public或friendly,不能写private和protected。
public class Person04 { //公有 public String name; //保护 protected String gender; //默认 double salary; //私有 private String jour; void say() { System.out.println("说..."); } void eat() { System.out.println("吃..."); } public Person04(String name, String gender, double salary, String jour) { this.name = name; this.gender = gender; this.salary = salary; this.jour = jour; }public static void main(String[] args) { Person04 p = new Person04("za","nan", 1212,"今天学习的java面向对象");
//1.本类中private、protected、frindly和public都可以访问 System.out.println(p.name); System.out.println(p.gender); System.out.println(p.salary); System.out.println(p.jour); } }
二、Java面向对象的特征之继承
1、继承的概念
将现实生活中事物之间的从属包含关系反映到计算机中的类描述时,可以通过继承体现。即:在开发一个类及其子类的过程中,让子类(派生类)自动具有该类的属性和成员方法。被继承者称为父类(超类、基类),继承者称为子类(派生类)。
2、继承的实现
在声明类的过程中,通过extends关键字来继承另一个类。如果构造方法的第一行没有显示调用父类的构造函数,则默认会在当前构造方法的第一行隐式调用父类的无参构造方法,即super();super的用法见另一篇博客——JAVA常用关键字super和this作用的介绍。
3、继承的特点
- 不支持多继承:java只支持单继承,不支持多继承。
- 不支持循环继承:java中继承禁止循环。
4、方法重写
当子类不喜欢从父类中继承的方法,而在本类中写一个同名同参数的方法来实现自子的逻辑,从而覆盖父类中的方法时,称之为产生了方法的重写。
可以在重写的方法前通过@Overdide告知编译器当前方法需要重写,利用编译器来检查方法名和参数使用是否正确。重写必须遵循的规则为:
- 方法签名必须一致(方法名、参数列表);
- 子类声明的访问权限修饰符的权限要大于等于父类声明的访问修饰符的权限;
- 如果父类中返回的值类型是基本数据类型或者void,则子类要保持一致;
- 如果父类方法返回值是类类型,则子类方法中的返回值可以是该类型或者其子孙类型。
具体示例如下所示:
package cn.tedu.extend; class A { } class B extends A{ }
//继承的特点: //1. java只支持单继承,不支持多继承 //2. java中继承禁止成环 class C extends B{ } class Person01 { private String name; private int age; public A say() { System.out.println("人说...."); return null; } public void eat() { System.out.println("人吃...."); } } class Teacher01 extends Person01 {
//方法重写的特点:子类返回类型C是父类的子类 @Override public C say() { System.out.println("老师在一本正经的说..."); return null; } //注解的作用:防止开发者误写,起到提示作用 @Override public void eat() { System.out.println("洗个手"); //super类似于父类的虚拟对象 super.eat(); System.out.println("抽根烟..."); } } public class Demo01 { public static void main(String[] args) { Teacher01 t = new Teacher01(); t.eat(); } }
三、Java面向对象的特征之多态
1、多态的概念
多态是同一行为具有多个不同表现形式或形态的能力。具体到程序中是指程序中定义的引用变量所指向的具体类型和引用能调用的方法在编程是并不能确定,而是在程序运行时才能确定该引用指向哪个类的实例对象。
重写和向上造型是多态的基础。
根据多态的绑定时期来划分可将多态分为:编译时多态(方法的重载)和运行时多态(向上造型和方法重写)。
2、重写
子类覆盖父类的方法,重新实现或者扩展功能即为重写。
3、向上造型
通俗来说,就是“子类当做父类使用”,即将子类的对象赋值该父类的引用。此时,该引用只能看到父类声明的方法和属性,调用方法时,调用的是子类的重写方法或继承自父类的方法;访问属性时访问的是父类的属性。
如果想使用子类中特有的方法,则只能强制转换为子类的引用之后才能调用。
示例如下所示:
class Person { public String name = "张三"; public void say() { System.out.println("人说...."); } public void eat() { System.out.println("人吃...."); } } class Teacher extends Person { public String name = "李四"; @Override public void say() { System.out.println("老师在一本正经的说..."); } public void teach() { System.out.println("老师在上课..."); } } public class Demo01 { public static void main(String[] args) { //1.--向上造型,子类当做父类用 Person t = new Teacher(); //2. 向上造型,父类引用只能看到父类声明的属性和方法 t.eat(); t.say(); //t.teach(); //4. 向上造型,如果父类引用想要看到子类身上特有的属性和方法, //需要进行类型的强制转换 Teacher teach = (Teacher)t; teach.teach(); //3. 向上造型,指向子类对象的父类引用调用的时子类的方法和父类的属性 t.say(); System.out.println(t.name); } }
4、多态的用处
基于重写和向上造型,我们可以在开发程序时,面向父类开发,但是在使用时用子类进行重写、扩展和改造父类的能力,调用方法时传入子类的对象,使程序执行子类定义的方法,为程序提供了很强的灵活性和扩展性。
多态本身是为了解耦。
多态的使用如下所示:
//Car类:所有车的父类 class Car { public void run() { System.out.println("在地上以30km/h速度跑..."); } } //汽车类:继承自父类car,改造了car,重写并增强了run方法 class Automobile extends Car { @Override public void run() { System.out.println("汽车在地上以60km/h速度跑..."); } } //火车类:继承自父类car,改造了car,重写并增强了run方法 class Train extends Car { @Override public void run() { System.out.println("火车在地上以120km/h速度跑..."); } } //若干年后开发出了飞车:同样继承自Car,重写run方法 class Aerodyne extends Car { @Override public void run() { System.out.println("飞车在以1200km/h速度飞..."); } } //Car类的使用者 class TranDemo { //方法中使用多态:面向父类开发,所有car的子类都可以接受 //没有和任何具体的car写死,后续可以继续开发Car的子类,进一步增强能力, //增加了灵活性。 //public void trans(Automobile car) { public void trans(Car car) { System.out.println("准备货物..."); car.run(); System.out.println("卸载货物..."); } } public class Demo02 { public static void main(String[] args) { Automobile auto = new Automobile(); Train train = new Train(); Aerodyne aero = new Aerodyne(); TranDemo trans = new TranDemo(); //可以传入汽车,火车,或者飞车auto,train,aero trans.trans(aero); } }