下面是学习面向对象的知识点和总结:
面向对象思想:
遇到需求,首先去找是否有现成的类来实现此功能,创建对象来调用,以此来组合成新的类实现自己的需求。
在java中是以类为单位,一个类包括成员变量、成员方法和构造方法
构造方法:创建对象的时候,由jvm自动调用,其中的作用是给成员变量赋值;不能用static关键字来修饰构造方法。
构造方法中也有return语句,只是一般不写;java中所有的方法中都有return语句,来进行出栈。
匿名对象:
public class Demo{ public void test(){} } // 利用匿名对象来调用Demo类 public class TestDemo{ public static void main(String args[]){ New Demo().test(); } }
使用匿名对象的使用场景:就是这个对象只用一次,这样的场景非常方便。
封装:
封装的目的就是隐藏;
为了数据安全,或者隐藏方法的内部实现过程,对外提供特有的方法进行访问;
下面就是把成员变量隐藏起来,通过设置get,set来对数据进行设置和读取:
package com.xiaoshitou.demo1; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
继承:
继承:子类继承父类的非私有的成员(成员变量和成员方法),注意:构造方法是不能被继承的。
class A{ } class B extends A{ }
类的继承只能是单一继承:也就是说一个子类只可以同时继承一个父类;
接口可以进行多重继承:一个接口可以同时继承多个接口
类可以进行多重继承:也就是说父类可以再继承其他的类
使用继承的时候:子类是父类的一种特殊情况的时候才使用继承;比如苹果是水果的其中一种,所有可以使用苹果类来继承水果类;
子类中有与父类同名的成员变量和方法时,可以使用super来调用父类的成员
super只能调用直接父类的成员,不能调用父类的父类的成员
方法的重写:
使用的场景:父类的方法不能满足子类的需求的时候,需要进行方法重写
子类和父类的方法一样时,当执行的时候,调用的是子类的方法,这就叫做重写
只有一般的方法才能重写,构造方法是不能被重写的
重写的格式:
1、方法名和参数列表必须相同
2、返回值一般要求相同,或者子类的返回值类型是父类方法返回值类型的子类
3、父类的方法有static修饰的时候,子类方法也必须用static修饰
4、子类方法 的权限不能比父类方法的权限低
子类实例化的过程:
JVM执行时,一旦遇到new关键字,就会到堆内存中开辟空间,得到这个空间的内存地址;
接下来根据类的成员,在堆中为类中成员变量分配空间,赋默认值;如果这个类有父类,则还要分配一块空间,用于保存父类中的成员变量;
再然后,就会调用相应的构造函数进栈执行;(也就是说,如果创建的是子类对象,此时调用的是子类的构造函数进栈);
构造函数进栈后,首先会执行一个隐式三步:
1、调用父类构造函数;(手动写,就是super(参数列表))默认调用的都是父类无参构造函数;
2、为对象中的成员变量显示初始化;
3、如果有构造代码块,执行构造代码块;
隐式三步都执行完毕,才开始执行构造函数中的代码;
当构造函数中的代码执行完毕后结束出栈,对象才算创建完成;
注意事项:
1、子类实例化,只会创建一个对象(就是子类对象),但是也会为父类成员变量分配空间;
2、子类构造函数执行时,会先执行父类构造函数,目的是给父类成员变量赋值;执行完父类构造函数才执行子类构造函数;
因为只是创建了一个子类的对象,所以如果调用的方法存在重写的情况下,就一定调用的是子类重写过的方法
创建子类的时候,调用父类的构造方法的原因是为了给父类的成员变量进行显示初始化
this和super关键字:
this代表当前调用的对象,所有的非静态成员方法和变量调用都需要依赖对象
this的作用:
1、区分局部变量和成员变量
2、在构造器方法中调用其他构造方法
在构造方法中调用其他构造方法时,必须把this(参数)放在第一行
super代表直接父类
当子类中的成员与父类同名时,可以用super来调用父类的成员
在子类的构造方法中可以使用super(参数)来调用父类的构造方法;如果不写默认会调用父类的无参数构造方法。
this和super调用构造方法时,不能同时存在,因为两个都必须放在第一行;当使用this来调用其他的构造方法时,是利用了间接的调用父类的构造方法
final关键字:
inal修饰类:该类不能被继承
final修饰方法:该方法不能被重写
final修饰变量:基本数据类型,成为了常量,不能被改变
引用数据类型,对应指向对象的地址不能改变
final不能修饰构造方法
抽象类:
抽象类:抽象类不能创建对象,也就是说不能new,必须由子类来继承
一个类继承抽象类继承抽象类,必须全部重写抽象方法,否则该类还是抽象类
一个类中存在抽象方法,就这个类必须声明成抽象类
抽象类可以存在所有的成员(常用变量,成员方法,构造方法)
使用场景:
1、类中有抽象方法
2、不希望被创建对象
多态:
多态就是:父类的引用指向子类的对象;或者是接口的引用指向实现类的对象
多态的使用前提:两个类存在继承关系,或者接口和接口实现类的关系
好处:提高了程序的扩展性,代码的复用性
多态编译时,全部看父类
多态运行时,除了存在重写的非静态方法,运行子类重写的方法,其他全部运行父类的成员。
类型转换:
向上自动转型:多态就属于自动向上转型
强制向下转型:可以先使用instanceof判断然后再进行强制转换,否则容易出现类型转换异常
接口:
接口中只有成员变量和成员方法
成员变量默认的是:public static final
成员方法默认的是: public abstract
这些修饰符可以写也可以不写,在编译的时候会自动加上
一个接口可以同时继承多个
一个类可以同时实现多个接口
类继承和实现可以同时进行,但是实现接口应该放在最后
注意:
不管是一个类实现多个接口,还是接口继承多个接口时,不能出现方法名和参数名相同,返回值类型不同的方法
接口和抽象类的使用场景:
- 抽象类:两个类存在继承关系
- 接口:两个事物不存在继承关系,主要用来定义规则,增加功能
static关键字:
类加载的过程:
包package:
权限修饰符:
内部类: