细说面向对象三大特征

面向对象特征之封装性

1. 为何要引入封装性?

咱们程序设计追求“高内聚,低耦合”java

  • 高内聚:类的内部数据操做细节本身完成,不容许外部干涉面试

  • 低耦合:仅对外暴露少许的方法用于使用。数据库

隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提升系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露岀来。这就是封装性的设计思想。this

2. 问题引入:

当咱们建立一个类的对象之后,咱们能够经过"对象.属性"的方式,对对象的属性进行赋值。这里,赋值操做要受到属性的数据类型和存储范围的制约。除此以外,没其余制约条件。可是,在实际问题中,咱们每每须要给属性赋值加入额外的限制条件。这个条件就不能在属性声明时体现,咱们只能经过方法进行限制条件的添加。(好比:setLegs()同时,咱们须要避免用户再使用"对象.属性"的方式对属性进行赋值。则须要将属性声明为私有的(private).spa

此时,针对于属性就体现了封装性。设计

3. 封装性思想具体的代码体现:

体现一:code

将类的属性xxx私化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值对象

private double radius;
public void setRadius(double radius){
	this.radius = radius;
}
public double getRadius(){
	return radius;
}

体现二:不对外暴露的私有的方法继承

体现三:单例模式(将构造器私有化)接口

体现四:若是不但愿类在包外被调用,能够将类设置为缺省的。

4. Java规定的四种权限修饰符

经过对不一样的方法属性设置不一样的权限修饰符来达到对类进行封装的目的。

4.1 权限从小到大顺序为:private < 缺省 < protected < public

4.2 具体的修饰范围:

修饰符 类内部 同一个包 不一样包的子类 同一个工程
private Yes      
(缺省) Yes Yes    
protected Yes Yes Yes  
public Yes Yes Yes Yes

4.3 权限修饰符可用来修饰的结构说明:

4种权限均可以用来修饰类的内部结构:属性、方法、构造器、内部类

修饰类的话,只能使用:缺省、public

面向对象特征之继承性

1.为何要有类的继承性?(继承性的好处)

  • 减小了代码的冗余,提升了代码的复用性
  • 便于功能的扩展
  • 为以后多态性的使用,提供了前提

image-20200327224109229

2.继承性的格式:

class A extends B{}
 *    A:子类、派生类、subclass
 *    B:父类、超类、基类、superclass

判断是否要进行继承:A is a B,若成立,则B继承A

3.子类继承父类之后有哪些不一样?

3.1体现:一旦子类A继承父类B之后,子类A中就获取了父类B中声明的全部的属性和方法。

特别的,父类中声明为private的属性或方法,子类继承父类之后,仍然认为获取了父类中私的结构。只由于封装性的影响,使得子类不能直接调用父类的结构而已。

3.2 子类继承父类之后,还能够声明本身特有的属性或方法:实现功能的拓展。

子类和父类的关系,不一样于子集和集合的关系。

extends:延展、扩展

4. Java中继承性的说明

  1. 一个类能够被多个子类继承。
  2. Java中类的单继承性:一个类只能有一个父类
  3. 子父类是相对的概念。
  4. 子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
  5. 子类继承父类之后,就获取了直接父类以及所间接父类中声明的属性和方法

image-20200331090341980

5. java.lang.Object类的理解

是Java中全部类的父类,相似于二叉树中的根节点,定义了一些通用的方法。

  1. 若是咱们没显式的声明一个类的父类的话,则此类继承于java.lang.Object类
  2. 所的java类(除java.lang.Object类以外都直接或间接的继承于java.lang.Object类
  3. 意味着,所的java类具备java.lang.Object类声明的功能。
  4. java.lang.Object类中定义的一些方法
方法名 类型 描述
public Object() 构造方法 构造器
public boolean equals( Object obj) 普通方法 对象比较
public int hashCode() 普通方法 获取Hash码
public String toString() 普通方法 对象打印时调用

面向对象的特征之多态性

1. 多态性的理解:

能够理解为一个事物的多种形态。好比数据库的链接方式,咱们定义好了数据库的链接,也规定了链接时的步骤,可是咱们并不知道用户会采用什么数据库,在没有多态之前咱们只能针对不一样的数据库写不一样的链接方法,而有了多态之后咱们只须要定义好数据库的类并书写好链接方法,让全部的数据库继承数据库类并重写数据库链接方法。这样咱们在调用的时候只须要经过声明数据库类并指向数据库的子类的方式,*(即数据库类的引用指向继承了数据库类的具体实现类的对象)*就能够进行数据库链接。而不是须要针对不一样的数据库书写不一样的链接方式。

2. 何为多态性:

对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)

编译时和运行时类型不一致,产生了多态

举例:

Person p = new Man();
Object obj = new Date();

3. 多态性的使用:虚拟方法调用

有了对象的多态性之后,咱们在编译期,只能调用父类中声明的方法,但在运行期,咱们实际执行的是子类重写父类的方法。

总结:编译,看左边;运行,看右边。

对象的多态:在Java中,子类的对象能够替代父类的对象使用

  • 一个变量只能有一种肯定的数据类型
  • 一个引用类型变量可能指向(引用)多种不一样类型的对象

4.多态性的使用前提:

① 类的继承关系 ② 方法的重写

5.多态性的应用举例:

举例一:
	public void func(Animal animal){//Animal animal = new Dog();
		animal.eat();
		animal.shout();
	}
举例二:
public void method(Object obj){
		
	}
举例三:
class Driver{
	
	public void doData(Connection conn){//conn = new MySQlConnection(); / conn = new OracleConnection();
		//规范的步骤去操做数据
//		conn.method1();
//		conn.method2();
//		conn.method3();
		
	}
	
}

6. 多态性使用的注意点:

对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)

个引用类型变量若是声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法

小结:

多态的做用:提升了代码的通用性,常称做接口重用

前提:
须要存在继承或者实现关系
有方法的重写

成员方法:
编译时:要查看引用变量所声明的类中是否有所调用的方法
运行时:调用实际new的对象所属的类中的重写方法

成员变量:
不具有多态性,只看引用变量所声明的类

7. 关于向上转型与向下转型:

7.1 向上转型:多态

7.2 向下转型:

7.2.1 为何使用向下转型:

有了对象的多态性之后,内存中其实是加载了子类特有的属性和方法的,可是因为变量声明为父类类型,致使编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。如何才能调用子类特的属性和方法?使用向下转型。

7.2.2 如何实现向下转型:

使用强制类型转换符:()

Person p = new Man();

Man m1=(Man)p2;//向下转型

7.2.3 使用时的注意点:

① 使用强转时,可能出现ClassCastException的异常。 ② 为了不在向下转型时出现ClassCastException的异常,咱们在向下转型以前,先进行instanceof的判断,一旦返回true,就进行向下转型。若是返回false,不进行向下转型。

只有对象A是B的子类实例化对象或者在下层的子类,才能向下转型

7.2.4 instanceof的使用:

① a instanceof A :判断对象a是不是类A的实例。若是是,返回true;若是不是,返回false。

② 若是 a instanceof A返回true,则 a instanceof B也返回true.其中,类B是类A的父类。

③ 要求a所属的类与类A必须是子类和父类的关系,不然编译错误。

p instanceif Man//左边是变量名,右边是类的类型

7.2.5 图示:

image-20200328170736290

8.面试题:

8.1 谈谈你对多态性的理解?

  1. 实现代码的通用性。
  2. 举例:
    • Object类中定义的public boolean equals(Object obj){ }
    • JDBC:使用java程序操做(获取数据库链接、CRUD)数据库(MySQL、Oracle、DB二、SQL Server)
    • 抽象类、接口的使用确定体现了多态性。(抽象类、接口不能实例化)

8.2 多态是编译时行为仍是运行时行为?

运行时行为

9.练习

class Base {
	int count = 10;

	public void display() {
		System.out.println(this.count);
	}
}

class Sub extends Base {
	int count = 20;

	public void display() {
		System.out.println(this.count);
	}
}

public class FieldMethodTest {
	public static void main(String[] args) {
		Sub s = new Sub();
		System.out.println(s.count);//20
		s.display();//20
		
		Base b = s;//多态性
		//==:对于引用数据类型来说,比较的是两个引用数据类型变量的地址值是否相同
		System.out.println(b == s);//true
		System.out.println(b.count);//10
		b.display();//20
	}
}

强调:

  1. 若子类重写了父类方法,就意味着子类里面定义的方法完全覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中:编译看左边,运行看右边
  2. 对于实例变量则不存在这样的现象,即便子类里定义了与父类彻底相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看左边
相关文章
相关标签/搜索