Java基础(个人总结)
- 面向对象
<1>
理解面向对象首先要明白何为对象
Java中的对象 非 现实中的对象
Java程序中的对象可以理解为是一个功能的集合
程序本身就是由多个功能实现的
而一个功能是由众多属性构成的
拿现实中举例子
一个人 是由头部 体部 腿部 组成的
而头部是由 眼睛 鼻子 嘴巴 构成的
眼睛是用来看这个世界的
鼻子用来呼吸空气
嘴巴用于吃饭或说话
我们代替一下:
程序(一个人)
对象(头部)
属性及行为(鼻子,眼睛,嘴巴<属性>。看,呼吸,吃饭<行为>)
这样是否对对象是什么由一些了解了呢?
**在Java中,所有类默认都有一个父类(Object)**
现在理解什么是面向对象编程
官方定义 :
面向对象程序设计以对象为核心,该方法认为程序由一系列对象组成。类是对现实世界的抽象,包括表示静态属性的数据和对数据的操作,对象是类的实例化。对象间通过消息传递相互通信,来模拟现实世界中不同实体间的联系。在面向对象的程序设计中,对象是组成程序的基本模块。
个人理解 :
一个程序是由多个对象组成,但是在设计程序的时候可以去模拟现实,通过现实来去划分各个功能(程序是服务现实的,所有程序的诞生都是因现实决定的)
比如 :
一家饭馆由多种菜品,基于现实
饭馆程序,由多个菜品对象构成,基于程序
IT,金融,物流 等都是行业中的一部分,基于现实
行业统计程序,用于统计各个行业,而每一个行业都可以细分为很多种
如 IT行业 : 有做UI,前端,后端 等等
程序是由对象组成,而对象可以拥有自己独立的特性,正是这些不同的特性得以支持一个程序的各种功能从而服务于用户
- 面向对象三大特征
<1>封装
个人理解 :
对属性的封装提供了程序的安全性,只能通过特定的方式去访问一个类中的属性
比如 :
public class Dog{
private String eyes;
private String mouth;
public String getEyes(){
return eyes;
}
public void setEyes(String eyes){
this.eyes = eyes;
}
}
我们声明了一个Dog类 ,其中有两个属性 一个是眼睛,一个是嘴
我们将其私有化,只提供get/set方法来让外界去访问 ,避免了外界通过实例化直接修改属性
,控制属性的访问权限提高了程序的安全性。
再此引申一下Java访问控制权限修饰符 :
public : 公开的,最大访问控制权限 。
private : 私有的,最小访问控制权限。
protected : 保护的,只有在同一包下的类,和子类可以访问用protected修饰的属性和方法
默认(default) : 有default关键字,但是应用于接口中。在类中并没有default访问控制修饰符
void add(){}
这个便是默认访问控制权限
访问权限修饰符 类 同包类 子类 不同包类
public 可 可 可 可
protected 可 可 可
default 可 可
private 可
<2>继承 :
继承是下一特性多态的前提
继承 :看下列代码
class Person_Jerry{
public void eat(){
System.out.println("Jerry在吃饭");
}
}
class Person_Tom{
public void eat(){
System.out.println("Tom在吃面");
}
}
class Person_Luci{
public void eat(){
System.out.println("Luci在吃米");
}
}
class Person_Roke{
public void eat(){
System.out.println("Roke在吃蛋糕");
}
}
通过上述代码,所有类都具有eat吃这个方法
代码重复性过高
而我们就可以通过继承去将共性代码抽取到父类中
class Person{
public void eat(){
}
}
class Person_Jerry extends Person{
@Override
public void eat(){
System.out.println("Jerry在吃饭");
}
}
class Person_Tom extends Person{
@Override
public void eat(){
System.out.println("Tom在吃面");
}
}
class Person_Luci extends Person{
@Override
public void eat(){
System.out.println("Luci在吃米");
}
}
class Person_Roke extends Person{
@Override
public void eat(){
System.out.println("Roke在吃蛋糕");
}
}
上述代码就是将共性代码抽取到父类之中,但是看起来甚至比不继承更麻烦
继续看下列代码
public class Main {
public static void main(String[] args) {
Person_Jerry pj = new Person_Jerry();
Person_Luci pl = new Person_Luci();
Person_Roke pr = new Person_Roke();
Person_Tom pt = new Person_Tom();
whoEat(pj);
whoEat(pl);
whoEat(pr);
whoEat(pt);
}
private static void whoEat(Person_Jerry pj){
pj.eat();
}
private static void whoEat(Person_Luci pl){
pl.eat();
}
private static void whoEat(Person_Roke pr){
pr.eat();
}
private static void whoEat(Person_Tom pt){
pt.eat();
}
}
对于同名方法但参数类型不同这种特性是重载(稍后会说)
回归正题 :
上述代码的客观性太低,如果不继承,只能这样调用或者去创建各个实例去调用各自的方法,而我们通过继承,就可以这样去通过下列代码去调用
public class Main {
public static void main(String[] args) {
Person_Jerry pj = new Person_Jerry();
Person_Luci pl = new Person_Luci();
Person_Roke pr = new Person_Roke();
Person_Tom pt = new Person_Tom();
whoEat(pj);
whoEat(pl);
whoEat(pr);
whoEat(pt);
}
private static void whoEat(Person p){
p.eat();
}
}
这样是否可以体现了继承的好处呢?
引申
上述代码我们也可以定义接口去实现 接口(interface) 并没有方法体,更加简便,但是却有弊端
代码 :
interface PersonInterface{
void eat();
void study();
}
class Person_Jerry implements PersonInterface{
public void eat(){
System.out.println("Jerry在吃饭");
}
@Override
public void study() {
}
}
class Person_Tom implements PersonInterface{
public void eat(){
System.out.println("Tom在吃面");
}
@Override
public void study() {
System.out.println("Tom在学习");
}
}
class Person_Luci implements PersonInterface{
public void eat(){
System.out.println("Luci在吃米");
}
@Override
public void study() {
System.out.println("Luci在学习");
}
}
class Person_Roke implements PersonInterface{
public void eat(){
System.out.println("Roke在吃蛋糕");
}
@Override
public void study() {
System.out.println("Roke在学习");
}
}
class Person_Lili implements PersonInterface{
@Override
public void eat() {
}
@Override
public void study() {
System.out.println("Lili在学习");
}
}
在Lili类并不想实现PersonInterface的eat方法,Jerry又不想实现父接口的study方法,这就是接口的弊端
个人理解 :
将所有子类的共有特性抽取到父类中 , 将只有某些子类共有的特性添加到接口中,因为Java只支持单继承,但接口可以多实现
可以去这篇文章去查看
《 Java 中到底是应该用接口类型 还是实现类的类类型去引用对象?》
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
<3>多态
向上转型:
要了解多态首先要知道多态的特性是什么
而向上转型(向上造型)就是多态的特性之一
而多态发生的前提是继承
** 向上转型 : 父类引用指向子类对象 **
接口与抽象类都不可以被实例化 , 而有一些情况下,比如接口的实现类并没有自
己的方法,我们就可以通过这个实现类去创建接口的引用
interface List{
void add();
void add(Object o);
void delete();
void delete(int index);
int size();
}
class MyList implements List{
@Override
public void add() {
/**
* 伪代码
*/
}
@Override
public void add(Object o) {
/**
* 伪代码
*/
}
@Override
public void delete() {
/**
* 伪代码
*/
}
@Override
public void delete(int index) {
/**
* 伪代码
*/
}
@Override
public int size() {
/**
* 伪代码
*/
return 0;
}
}
这种情况下我们就可以通过实现类去创建List引用
List list = new MyList();
这就是向上转型
多态1.1 重写
重写(Override) : 重写只发生在父子类之中
对父类的方法进行覆盖,上述继承中就运用了重写
重写的好处 : 子类可以根据自己的需要去定义自己的行为方式
比如 : 父亲的喜欢吃饭 儿子喜欢吃面
通过代码表示 :
class Father{
public void eat(){
System.out.println("I like eat meal");
}
}
class Son extends Father{
@Override
public void eat(){
System.out.println("I like eat noodle");
}
}
子类拥有父类的属性父类的行为,但是子类的行为模式并不与父类完全相同
暂时整理到这里,有些理念并不是特别完善,所以希望大佬们可以帮忙查缺补漏
只是个人总结,看这篇文章的时候带着辨证的角度去看,希望有些理念不要误导初学者。