当时大二刚学Java时对面向对象这个抽象的概念很是迷惑,在系统学习了解后,本人将其主要精华做了大致整理,对于小白较为友好,在此分享出来。
理解这些概念可初步掌握面向对象主要知识点。
路漫漫其修远兮,吾将上下而求索。本人书写博客难免有不当之处,还请各位大佬给予指正,万分感激~
面向过程的缺点:
1、数据和方法是分离的
2、缺乏对数据的封装(致命缺点)
面向对象 Object Oriented Programming
·1 抽象数据类型:可以将不同类型数据的集合组合成一个整体,
从而让这个整体去描述新的事物
·2 什么叫做类(class);什么叫做对象(万物皆对象)
类:现实世界是由很多对象组成的基于对象而抽取出来的叫类
对象:对象是真实存在的单个个体
·注意:类指的是类型,代表一类个体,类和对象的概念是相对的
·3 类中可以包含什么东西?
1、所有对象所共有的属性 ----变量
2、所有对象所共有的行为 ----方法
总结:(类和对象)
一个类可以创建多个对象,同一个类型创建的对象结构相同数据不同
总之类是对象的模板,对象是类的具体实例
· 4创建对象:
类似于:student s = new student();
类 引用类型变量 new运算 对象
注意:创建对象后类中的变量都有默认值
上述例子中的‘s’ 为引用类型变量,若对象创建成功,该‘s’中存的是地址
若对象没有创建成功,该‘s’中存的是空
若's'为空就不能用它去寻找对象,因为会出现 NullPointerException(空指针异常)
引用类型变量之间赋值传递的是地址
1.类中的属性:
就是类中的变量,属于直接写在类里面的变量,通常把这类变量叫成员变量
注意:如果是在方法中声明的变量千万不能叫做成员变量
在方法中声明的变量叫局部变量
成员变量初始化:
a、在声明变量的时候直接赋值(相当于把该变量写死,不建议使用)
b、创建对象后,用引用类型变量去访问或赋值
c、用构造器(构造方法)赋值,构造器只是用来为成员变量赋值
构造方法的使用需知:
a、只要创建了一个类,系统就会为当前类默认生成一个无参数的构造器
b、构造方法的名字必须和类名一致
c、构造方法没有返回值,也不能写void
d、在创建对象的时候自动调用该类的构造方法
e、若自己不写构造方法系统会默认提供一个无参数的构造方法
若自己写了构造方法系统就不提供了
区分成员变量和局部变量的方式:
只要在成员变量前加(this.)就可以代表成员变量
this关键字:总结
this.变量名 ---代表访问成员变量
this(参数列表) ---代表调用和参数列表匹配的构造方法
this.方法名字() ---代表调用方法
2.类中的方法:
直接写在类中的方法称之为:成员方法(简称:方法)
注意:在类中不能出现方法名字和参数列表都相同的方法
方法的重载:在一个类中,出现方法名字相同,参数列表不同的方法均为方法的重载
方法重载的调用:在调用的时候根据参数列表的不同,实现对不同方法的调用
对象的内存管理:
在JVM虚拟机中,先把.JAVA的文件转化为.class的文件,该.class的文件称之为:字节码文件
该字节码文件储存着类的信息(指的是该类的属性和方法),若编程人员要使用该类就必须实例化该类型(new对象)
只要实例化JVM会把内存分为三个区域给大家使用 :
1.方法区: 1、主要是用来储存 .class 字节码文件。也就是说他储存的是类的信息
2、储存 static修饰的对象中的成员变量和成员方法
注意: 方法区中储存的是类的信息,只有一份不论后期你创建多少个对象,储存在方法区中的内容只有一个
2. 堆 :1、主要用来储存所有new出来的对象
2、储存没有被 static修饰的成员变量成员方法
补充:在堆当中如果该对象没有任何引用类型变量指向的时候,那该对象就会被视为垃圾
内存溢出:创建的对象过多或者垃圾对象没办法进行清理,造成的堆溢出
线程:垃圾回收机制 简称 GC
注意:以后在new对象的时候,当程序中已经使用完该对象的时候,需要把当前对象所指代的引用类型变量赋值为null .close()
3. 栈 : 1、存创建对象的时候所有引用类型的变量,除此之外,还有成员方法中创建的局部变量。
补充:
成员变量的生命周期:
局部变量的生命周期:当调用方法的时候开始到方法结束的时候
数组:用来存放一组数据类型相同的数据结构
引用类型数组:
是用来储存一组类型相同的对象的数据结构
比如 :字符串类型 String[] arr = new String[4];
引用类型数组声明:
Cell[] wc = new Cell[4];
引用类型数组的初始化(赋值):
eg: wc[0] = new Cell(3,2);
wc[1] = new Cell(5,6);
wc[2] = new Cell(6,7);
wc[3] = new Cell(9,10);
Cell wk = new Cell[4]{new Cell(3,2),new Cell(5,6),new Cell(6,7),new Cell(9,10)};
二维数组:(数组类型的数组)
声明:
int[][] arr = new int[3][];
初始化:
arr[0] = new int[3];
arr[1] = new int[4];
arr[2] = new int[3];
eg:向arr数组中的第一个位置上的数组中的第一位赋值为5
arr[0][0] = 5;
向arr数组中的第一个位置上的数组中的第二位赋值为5
arr[0][1] = 5;
继承:
(主要用来对多个类进行统一化管理,建立父类和子类的继承关系:所有子类可以享用父类中的一切,父类可以管理所有的子类)。
1·实现继承的步骤:
一、观察所有类型,把所有类型中相同的属性和方法提出来
二、建立父类,把上一个步骤中的相同代码提出来放在父类中,然后让其他类都继承该父类
2·继承的意义: 1、降低了代码重用率
2、使管理效率更高
3·继承的要点:
通过extends关键字实现继承
父类:所有子类共有的代码
子类:子类所特有的特征和行为
注意: Java中一个父类可以有多个子类,一个子类只能有一个父类
*** java规定:如果调用子类构造方法之前是必须先调用父类的构造
如果子类构造器中没有调用父类构造器的代码的话,是因为系统会默认生成一个super去调用父类的构造
4·super关键字:
1、如果父类中的构造为无参构造,子类构造方法中系统会默认生成super()去先调用父类构造器。
如果父类中自己写了有参构造,则需手动在子类构造方法的第一行加上对应参数的 super(xxxx)
5·向上造型:
父类的引用指向子类的对象
如果调用对象时采用向上造型,那么该引用类型变量能调用的东西是父类中所有子类共有的属性和方法
如果采用向上造型的时候执行的方法或者赋值的变量都是操作的子类
6·重写:
发生在父子类中出现方法名字相同参数列表相同,方法内部实现不同的现象称之为方法的重写
补充:在向上造型里面,调用重写方法的时候执行的都是引用类型变量对应的对象中的方法
*** 总结:重写看对象
重载回顾:
发生在同一个类中,方法名字相同,参数列表不同。
补充:重载方法因为发生在一个类中所以和对象没关系
*** 总结:重载看类型 (参数列表类型)
抽象方法:
在父类中为了更好地去封装所有子类共有的那个方法,
Java提供抽像方法的概念,让方法只声明不写方法体。
·由abstract修饰,写在修饰符后面
·只有方法定义没有方法的具体实现(不写{})
抽象类:
只要在当前类中出现了抽象方法那么该类也必须写为抽象类
如果该类成为抽象类,就在类的访问修饰符后+abstract
***抽象类是不能被实例化的(不能new对象)
抽象类是必须要被继承,如果某个子类一旦继承该抽象类,必须在子类中重写其抽象方法
抽象类的意义:(抽象父类的意义)
1、封装子类所共有的数据和行为(成员变量和方法),这样减少了代码重复率
2、父类的出现,为所有子类提供了一个公共类型
3、如果父类中包含抽象方法,那么该抽象方法就给其他调用者提供一个标准入口
接口:
·它可以封装某几个子类的共同行为,由interface修饰
·在接口中只能写抽象方法和常量
注意:接口声明常量的时候可以不写“public static final”系统会自动生成
接口中封装的抽象方法可以不写“public abstract”
·接口不能被实例化(不能new对象)
·接口一定要被实现(继承),实现接口的类为该接口的子类,
需要在子类中用implements去实现该接口,在实现类中必须重写接口中的抽象方法
·一个类可以实现多个接口,接口可以继承接口
Package:
包:避免类名冲突。(相当于文件夹)
包名:建议用英文字母 小写 不能数字开头;在企业中会分层建立包名
Import:
1、如果在调用同包中的类无需import
2、在调用不同包中的类时,必须有import,但是无需自己写,快捷生成
访问控制修饰符:
public:公开的,任何类都可以调用
private:私有的,其他任何类都不能调用,只有本类内部可以调用
protected:受保护的,只能被本类、子类、同包中的类调用
默认的:只能被同包中的类调用
注意:如果用修饰符修饰类只能使用public 和 默认两种方式,
但是大部分情况都使用public来修饰类。
如果用来修饰成员变量和方法的话 数据私有化 行为公开化
Static关键字:
我们称static为静态的,通常static用来修饰成员变量和方法,不修饰局部变量
除了这两种常用方法之外我们也可以在类中去写静态块。
用static修饰成员变量:
·如果没有被static修饰的成员变量称之为实例变量
实例变量:
属于对象,存在堆中 对象有几个该实例变量就有几个
通过引用类型变量+“.”来进行访问
·如果被static修饰的成员变量称之为静态变量
***静态变量:
1、静态变量属于类的信息,存在方法区中
2、因为静态变量和对象没有关系,所以通过类+‘.’来调用
3、静态变量只有一份无论你创建多少对象
何时用static修饰成员变量:
如果一个类中出现了某些成员变量的值被其他所有对象共用的时候就static
用static修饰方法:
·如果没有被static修饰的方法是属于对象的,通过引用类型变量+‘.’来调用,
创建多少个对象就会有多少个方法。
·如果被static修饰的方法是静态方法
静态方法:
static通常写在访问控制修饰符的后面。
一旦方法被static修饰,该方法就属于类,存在方法区中,
无论创建多少个对象,静态方法只有一份。
调用的时候,通过类名‘.’方法名。
***如果是静态方法,那么在静态方法内部是不能去直接调用实例变量的,
但是可以直接使用静态变量。
何时用:方法的使用仅与参数有关,与对象无关的时候使用
静态块:
static修饰,实际上它是一个特殊的方法 ,该静态块不能被调用,当类被加载的时候使用,
因为在Java中类只会被加载一次所以静态块就只会执行一次
何时用:常常用静态块来加载外部的资源(图片、音乐、视频)
final关键字:
修饰类:类不能被继承
修饰方法:方法不能被重写
修饰成员变量:变量不能被改变
修饰局部变量:使用之前一定要被赋值
static final:常量
1、如果修饰成员变量,那么该成员变量称之为常量
常量必须声明的时候就初始化并且值不能被改变
常量通过类名‘.’来调用,建议常量的变量名全部取为大写。
在编译的时候,常量会被替换成具体数值
接口:
·它可以封装某几个子类的共同行为,由interface修饰
·在接口中只能写抽象方法和常量
注意:接口声明常量的时候可以不写“public static final”系统会自动生成
接口中封装的抽象方法可以不写“public abstract”
·接口不能被实例化(不能new对象)
·接口一定要被实现(继承),实现接口的类为该接口的子类,
需要在子类中用implements去实现该接口,在实现类中必须重写接口中的抽象方法
·一个类可以实现多个接口,接口可以继承接口
匿名内部类:
Java中接口是必须要被实现的,所以需要创建一个类去实现该接口并重写该接口中的方法。
完成该过程后,编程人员可以创建无数个实现子类的对象。
如果创建了一个子类,并实现了某个接口,在创建该子类对象的时候,该对象只需创建一次
(指的是只会创建一个子类对象之后就不会再创建了)我们可以不写改实现类的类名。
这个过程就叫匿名内部类。
多态:
回顾:向上造型:父类的引用指向子类的对象,在调用的时候能调父类中封装的属性和行为
执行的属性和行为是子类对象内部的。
上述向上造型,就是多态的一部分
所谓多态:指的是类中行为的多种状态
·同一个类型的引用在指向不同对象的时候有不同的实现
·同一个对象被造型为不同类型的时候会有不同的功能