理解Java-面向对象

面向对象三大特征和七大原则

三大特征

封装

封装就是对属性和方法的载体类,只能通过其提供的接口(方法)来访问,而把实现细节隐藏起来.也就是说,具体实现对程序员来说是透明的,封装的好处在于对类内部的改变,不会影响到其他代码

  • 封装的做法: 私有属性(private修饰符修饰属性)、提供public的读(getXX)写(setXX)方法、在构造中调用方法.所有的非常量属性基本都需要封装.
  • 封装的好处:隐藏类的实现细节、对所有用户提供统一的接口、增强执行效果、易于维护和扩展
继承

继承是一种关系,逻辑上满足子类is a 父类的关系才使用继承. 子类继承父类的属性和非私有方法.不能继承父类的构造,继承使用关键字extends,类单继承,接口多继承.

  • 在构造子类对象时,依次调用父类的构造(子类默认调用父类的无参构造.可以使用super(参数列表)来调用指定的父类的含参构造)到Object为止.再调用子类自身的; 子类调用父类的构造时,父类的构造只能调用一个且必须写在子类构造的第一句.
多态

多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题; 多态的类型有下面4种:

基本类型的多态: 拆箱、装箱.

本质上是基本类型之间的自动类型转换,Java语言中将8种数据类型都分别封装了一个类,这些类中封装了各基本数据类型的属性和基本运算.

基本类型自动转换为对应的封装类的操作叫做自动装箱操作,反之叫自动拆箱操作,自动装箱操作有一个自动装箱池(范围为-128~127).只要自动装箱的数在自动装箱池范围内,则直接去池中找数据.

方法的多态: 重载、重写.
  • 重写(overriding): 父类继承过来的方法对子类不合适时子类可以改变该方法的实现,这种操作叫做方法的重写/覆盖(继承是重写的前提条件);
    重写要求:
    1、返回值、方法名和参数相同((5.0以后允许返回子类类型));
    2、子类异常不能超出父类异常;
    3、子类访问级别不能低于父类访问级别.

  • 重载(overloading): 重载是在同一个类中存在两个或两个以上的同名方法,但是参数不同(参数个数不同、类型不同、顺序不同<(int,String)和(String,int)是不一样的>),方法体也不相同. 返回值类型可以相同可以不相同.最常用的重载例子便是构造函数。

类或者接口的多态: 父类的引用指向子类的对象

父类的引用指向子类的对象(Person p = new Student())就发生了多态, 该场景下:

  • 只能使用父类中方定义的属性和方法
  • 子类中定义的不能直接使用
  • 子类复写了父类的方法,此时调用情况根据方法是否static而不同 [static(调用父类),非static(调用子类)].
  • 如果想使用子类中定义的方法,可以强制类型转换(判断是否可以转换,用instance of运算符来判断对象的类型)

程序示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class A {
int a = 1;
static int b = 20;
int c = 3;
double d = 2.0;

void show() {
System.out.println("Class A: a=" + a + "\td=" + d + "\tc=" + c + "\tb=" + b);
}

void common(){
System.out.println("Class A: method common()");
}

static void execute(){
System.out.println("Class A: method excute()");
}
}

class B extends A {

float a = 3.0f;
static int b = 30;
int c = 5;
String d = "Java program.";

void show() {
super.show();
System.out.println("Class B: a=" + a + "\td=" + d + "\tc=" + c + "\tb=" +b);
}

void common(){
System.out.println("Class B: method common()");
}

static void execute(){
System.out.println("Class B: method execute()");
}

public static void main(String[] args) {
A a = new B();
a.show();
System.out.println("----------------------");
a.common();
System.out.println("----------------------");
a.execute();
}
}

执行输出

1
2
3
4
5
6
Class A: a=1    d=2.0    c=3    b=20
Class B: a=3.0 d=Java program. c=5 b=30
----------------------
Class B: method common()
----------------------
Class A: method excute()
传参时的多态

基本类型的多态与类类型的多态混合使用, 这里会涉及常见面试题: Java中的参数传递是传传递还是传引用?
解答: Java语言的方法调用只支持参数的值传递, 当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。

程序示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Test {

public static void invoke(int num, Person person){
num = 222;
person.setAge(20);
person.setName("李四");
System.out.println(num + "," + person.getName() + "," + person.getAge());
}

public static void main(String[] args) {
int num = 111;
Person person = new Person("张三", 10);
invoke(num, person);
System.out.println(num + "," + person.getName() + "," + person.getAge());
}

@Data
static class Person{

public Person(String name, int age) {
this.name = name;
this.age = age;
}
private String name;

private int age;

}
}

程序输出

1
2
222,李四,20
111,李四,20

七大原则

  1. 单一职责原则(一个类只做它该做的事情)、
  2. 开闭原则(更改性封闭,扩展性开放)、
  3. 依赖倒转原则(面向接口编程)、
  4. 里氏替换原则(任何时候都可以用子类型替换掉父类型)、
  5. 接口隔离原则(接口要小而专,绝不能大而全)、
  6. 合成复用原则(优先使用聚合或合成关系复用代码)、
  7. 迪米特原则(对象与对象之间应该使用尽可能少的方法来关联)

说明: https://www.cnblogs.com/Smile-123/p/5385663.html