面向过程与面向对象
前言
本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!
也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!让我们在成长的道路上互相学习,欢迎关注!
上一篇:类和对象解析
一、面向过程(POP) 与 面向对象(OOP)
1. 两者的联系与区别
1.1 联系
1.2 区别
1.3 图解举例
2. 面向对象的三大特征
二、面向对象的特征一:封装性
1. 概述
1.1 引入:为什么需要封装?
⭕原因一:
⭕ 原因二:
1.2 特点
2. 使用
四种修饰符的修饰范围:
修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
---|---|---|---|---|
private | Yes | |||
(缺省) | Yes | Yes | ||
protected | Yes | Yes | Yes | |
public | Yes | Yes | Yes | Yes |
3. 注意
4. 应用举例
public class AnimalTest {
public static void main(String[] args) {
Animal a = new Animal();
a.name = "大黄";
// a.age = 1;//The field Animal.age is not visible
// a.legs = 4;//The field Animal.legs is not visible
a.show();
// a.legs = -4;
// a.setLegs(6);
a.setLegs(-6);
// a.legs = -4;//The field Animal.legs is not visible
a.show();
System.out.println(a.name);
}
}
class Animal{
String name;
private int age;
private int legs;//腿的个数
//对属性的设置
public void setLegs(int l){
if(l >= 0 && l % 2 == 0){
legs = l;
}else{
legs = 0;
// 抛出一个异常(暂时没有讲)
}
}
//对属性的获取
public int getLegs(){
return legs;
}
public void eat(){
System.out.println("动物进食");
}
public void show(){
System.out.println("name = " + name + ",age = " + age + ",legs = " + legs);
}
//提供关于属性age的get和set方法
public int getAge(){
return age;
}
public void setAge(int a){
age = a;
}
}
三、面向对象特征之二:继承性
1. 概述
1.1 引入:为什么要有继承?
2.使用
2.1 类继承语法规则
2.2 作用
3. 注意
代码演示:
class SubDemo extends Demo{ } //ok
class SubDemo extends Demo1,Demo2...//error
图解:
4. 应用举例
//为描述和处理个人信息,定义类Person:
class Person {
public String name;
public int age;
public Date birthDate;
public String getInfo() {
//...
}
}
//为描述和处理学生信息,定义类Student
class Student {
public String name;
public int age;
public Date birthDate;
public String school;
public String getInfo() {
// ...
}
}
//通过继承,简化Student类的定义:
class Person {
public String name;
public int age;
public Date birthDate;
public String getInfo() {
// ...
}
}
class Student extends Person {
public String school;
}
/*
Student类继承了父类Person的所有属性和方法,
并增加了一个属性school。Person中的属性和方法,Student都可以使用。
*/
四、面向对象特征之三:多态性
1. 概述
1.1 何为多态性?
2. 使用
2.1 作用
2.2 虚拟方法调用
2.3 使用前提
3. 注意
代码演示:
public class Test {
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
}
}
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);
}
}
代码演示:
Person p = new Student();
Object o = new Person();//Object类型的变量o,指向Person类型的对象
o = new Student(); //Object类型的变量o,指向Student类型的对象
代码演示:
Student m = new Student();
m.school = “pku”; //合法,Student类有school成员变量
Person e = new Student();
e.school = “pku”; //非法,Person类没有school成员变量
/*
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。
*/
4. 应用举例
(1)方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法
public class Test {
public void method(Person e) {
// ……
e.getInfo();
}
public static void main(Stirng args[]) {
Test t = new Test();
Student m = new Student();
t.method(m); // 子类的对象m传送给父类类型的参数e
}
}
(2)虚拟方法调用(Virtual Method Invocation)
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
/* 编译时类型和运行时类型
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。——动态绑定
*/
5. 区分方法的重载与重写(从编译和运行的角度)
6. 面试题:证明多态是编译时行为还是运行时行为?
//证明如下:
class Animal {
protected void eat() {
System.out.println("animal eat food");
}
}
class Cat extends Animal {
protected void eat() {
System.out.println("cat eat fish");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("Dog eat bone");
}
}
class Sheep extends Animal {
public void eat() {
System.out.println("Sheep eat grass");
}
}
public class InterviewTest {
public static Animal getInstance(int key) {
switch (key) {
case 0:
return new Cat ();
case 1:
return new Dog ();
default:
return new Sheep ();
}
}
public static void main(String[] args) {
int key = new Random().nextInt(3);
System.out.println(key);
Animal animal = getInstance(key);
animal.eat();
}
}