Object oriented programming(面向对象的程序设计)
面向对象编程是什么?
将现实的事物抽象出来,把现实生活的事物以及关系,抽象成类,通过继承,实现,组合的方式把万事万物都给容纳了。实现了对现实世界的抽象和数学建模。这是一次飞跃性的进步。
因此,面向对象编程有以下的特征:
面向对象的三大特性:
1、封装[
](https://baijiahao.baidu.com/s?id=1610193527339784483&wfr=spider&for=pc)
隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
(1).封装的优点
-
良好的封装能够减少耦合。
-
类内部的结构可以自由修改。
-
可以对成员变量进行更精确的控制。
-
隐藏信息,实现细节。
(2)关键词
this:采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
public、private
在方法和属性前边加上private后,就封装了某些属性和某些方法,他们就不会对外公开了。
2、继
承
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
}
}
继承的规则:
1参数列表必须完全与被重写方法的相同。
2返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
3访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
4父类的成员方法只能被它的子类重写。
5声明为 final 的方法不能被重写。
6声明为 static 的方法不能被重写,但是能够被再次声明。
子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和
的方法。
但是如果要访问被private修饰的属性可以(任何要访问类中私有成员变量的类都要)通过一些getter和setter(例如先setname后getname)方法得到返回值。
子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
构造方法不能被重写。
如果不能继承一个方法,则不能重写这个方法。
3,父类的东西,子类可以全部继承吗?
不,当然不是;
3.1权限修饰符的继承问题
被private修饰的,是不可以被继承的,因为private修饰的只能在本类中可见,子类是不可见的;另外父类被protected或public修饰的,子类是可以继承的;被默认修饰符修饰的只能在同包下的子类是可以继承的;
3.2 构造器的继承问题
构造器是不会被子类继承的,但子类的对象在初始化时会默认调用父类的无参构造器,当父类显示写了有参构造器,且没有无参构造器。子类继承父类的时候必须显示的调用父类的有参构造器。调用的方式可以使用super(a,b)来调用;
public Manager(String name,double salary,int year,int month,int day){
//子类调用父类构造器一定要放在语句最前面
super(name,salary,year,month,day);
bonus = 0;
}
3.3 static修饰符的继承问题
子类是不会继承父类被static修饰的方法和变量,但是可以调用(子类可以创建一个类似父类的static方法);如图所示,this.a()就会报错,普通方法的继承this.method_a()就不会报错;
```java
重写是发生在方法层面上的,属性是不会重写的,可以被隐藏,隐藏是针对于静态方法和静态属性的。另外重写是针对于实例方法的,子类的实例方法不能覆盖父类的静态方法,子类的静态方法不能隐藏父类的实例方法;
4.1,即要重写的方法的方法名和参数列表必须相同,可以在要重写的方法的上方添加@Override注解,来判断是否正确的进行了重写;
4.2 即子类的返回值类型和抛出的异常类型必须要小于等于父类的类型如下图:
4.3 要重写的方法的权限修饰符必须要大于等于父类方法的权限,不然就会报错,(private<public)
超类中的有些方法对子类不一定适用,需要子类提供一个新的方法来覆盖超类中的这个方法:(即重写)
//超类
public class Employee{
...
public double getSalary(){
return salary;
}
}
//子类,经理类不仅仅是返回工资 还有奖金的
public class Manager extends Employee{
...
//覆盖超类的getSalary方法
public double getSalary(){
return salary+bonus; //不起作用
}
}
上述覆盖是不起作用的,因为子类不能直接访问超类(员工类)的私有域,所以可以使用特定关键字super,以下是改进:
public double getSalary(){
return super.getSalary()+bonus;
}
重写是发生在方法层面上的,属性是不会重写的,可以被隐藏,隐藏是针对于静态方法和静态属性的。另外重写是针对于实例方法的,子类的实例方法不能覆盖父类的静态方法,子类的静态方法不能隐藏父类的实例方法;
[子类只有一个父类]默认继承Object类,Object是所有的父类。在java中只有直接父类和间接父类关系,没有兄弟关系,爷孙关系。
提高代码复用性;继承是多态的前提。
(1)优点
1用来提高代码的复用性
2将相同的功能模块封装到方法中需要使用时调用方法达到代码复用的目的
3通过继承将多个类中的相同的类容摘取出来,变成一个新类,让其他类和当前的新类产生关系,达到代码复用性的目的
(2)成员属性,成员方法,静态属性,静态方法,构造方法
(3)关键词:
this一是引用隐式参数。
二是调用该类其他构造器。
super当需要在子类中调用父类的被重写方法时,要使用 super 关键字。调用父类的方法。
1调用父类的构造器。
2通过super关键字来实现对父类成员的访问,用来引用当前对象的父类,super与this引用不是类似的概念,因为super不是一个对象引用,不能将super赋给另一个对象变量,它只是一个指示编译器调用超类方法的特殊关键字,super指向父类,this是指向自己的引用。
protected
继承是多态的基础。。。方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
[重写]是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
[重载]是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
3、多态[
](https://www.runoob.com/java/java-polymorphism.html)[多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作]
父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。
多态的优点
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
多态性就是父类的某个方法被子类重写时,可以各自产生自己的功能行为。
多态的一大作用就是为了解耦–为了解除父子类继承的耦合度。如果说继承中父子类的关系式IS-A的关系,那么接口和实现类之之间的关系式HAS-A。简单来说,多态就是允许父类引用(或接口)指向子类(或实现类)对象。很多的设计模式都是基于面向对象的多态性设计的。
[isa是继承关系,比如人是动物,人和动物是继承关系;
hasa是聚合关系,比如人有眼睛。]
补充:
虚函数
虚函数的存在是为了多态。
Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数。