面向对象三大特征

  • 封装
  • 继承
  • 多态

1、封装

将一些细节隐藏,对外界不可见

在java中的体现:

  • 方法就是一种封装
  • 关键字private也是一种
  1. 方法
    例如求数组的最大元素,可以将过程封装为一个方法getMax(),在main中只需调用该方法即可,无需关注具体细节
public class GetMax {public static void main(String[] args) {int[] array = {11, 3, 5, 8, 10};//        int max = array[0];
//        for (int i = 1; i < array.length; i++) {//            if (array[i] > max)
//                max = array[i];
//        }
//
//        System.out.println(max);System.out.println(getMax(array));}static int getMax(int[] array){int max = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > max)max = array[i];}return max;}}
  1. 关键字private
/*
问题描述:定义Person的年龄时,无法阻止不合理的数值被设置进来。
解决方案:用private关键字将需要保护的成员变量进行修饰。一旦使用了private进行修饰,那么本类当中仍然可以随意访问。
但是!超出了本类范围之外就不能再直接访问了。间接访问private成员变量,就是定义一对儿Getter/Setter方法必须叫setXxx或者是getXxx命名规则。
对于Getter来说,不能有参数,返回值类型和成员变量对应;
对于Setter来说,不能有返回值,参数类型和成员变量对应。*/
public class Person {String name; // 姓名private int age; // 年龄public void show() {System.out.println("我叫:" + name + ",年龄:" + age);}// 这个成员方法,专门用于向age设置数据public void setAge(int num) {if (num < 100 && num >= 9) { // 如果是合理情况age = num;} else {System.out.println("数据不合理!");}}// 这个成员方法,专门私语获取age的数据public int getAge() {return age;}}

2、继承

1. 在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式:

  • 直接通过子类对象访问成员变量:
    等号左边是谁,就优先用谁,没有则向上找。
  • 间接通过成员方法访问成员变量:
    该方法属于谁,就优先用谁,没有则向上找。
Fu fu = new Fu(); // 创建父类对象
System.out.println(fu.numFu); // 只能使用父类的东西,没有任何子类内容
System.out.println("===========");Zi zi = new Zi();
Fu fuzi = new Zi();System.out.println(zi.numFu); // 10
System.out.println(zi.numZi); // 20
System.out.println("===========");// 等号左边是谁,就优先用谁
System.out.println(zi.num); // 优先子类,200
System.out.println(fuzi.num); // 100
// System.out.println(zi.abc); // 到处都没有,编译报错!
System.out.println("===========");// 这个方法是子类的,优先用子类的,没有再向上找
zi.methodZi(); // 200
// 这个方法是在父类当中定义的,
zi.methodFu(); // 100
public class Fu {int numFu = 10;int num = 100;public void methodFu() {// 使用的是本类当中的,不会向下找子类的System.out.println(num);}}
public class Zi extends Fu {int numZi = 20;int num = 200;public void methodZi() {// 因为本类当中有num,所以这里用的是本类的numSystem.out.println(num);}}

2. 重写(Override)

概念:在继承关系当中,方法的名称一样,参数列表也一样。

重写(Override):方法的名称一样,参数列表【也一样】。覆盖、覆写。
重载(Overload):方法的名称一样,参数列表【不一样】。

方法的覆盖重写特点:创建的是子类对象,则优先用子类方法。

方法覆盖重写的注意事项:

  1. 必须保证父子类之间方法的名称相同,参数列表也相同。
    @Override:写在方法前面,用来检测是不是有效的正确覆盖重写。
    这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。

  2. 子类方法的返回值必须【小于等于】父类方法的返回值范围。
    小扩展提示:java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类。

  3. 子类方法的权限必须【大于等于】父类方法的权限修饰符。
    小扩展提示:public > protected > (default) > private
    备注:(default)不是关键字default,而是什么都不写,留空。

3. 关键字super和this

super关键字的用法有三种:

  1. 在子类的成员方法中,访问父类的成员变量。
  2. 在子类的成员方法中,访问父类的成员方法。
  3. 在子类的构造方法中,访问父类的构造方法。

super关键字用来访问父类内容,而this关键字用来访问本类内容。用法也有三种:

  1. 在本类的成员方法中,访问本类的成员变量。
  2. 在本类的成员方法中,访问本类的另一个成员方法。
  3. 在本类的构造方法中,访问本类的另一个构造方法。

在第三种用法当中要注意:
A. this(…)调用也必须是构造方法的第一个语句,唯一一个。
B. super和this两种构造调用,不能同时使用。


4. 抽象方法
抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束。
抽象类:抽象方法所在的类,必须是抽象类才行。在class之前写上abstract即可。

如何使用抽象类和抽象方法:

  1. 不能直接创建new抽象类对象。
  2. 必须用一个子类来继承抽象父类。
  3. 子类必须覆盖重写抽象父类当中所有的抽象方法。
    覆盖重写(实现):子类去掉抽象方法的abstract关键字,然后补上方法体大括号。
  4. 创建子类对象进行使用。

注意:
一个抽象类不一定含有抽象方法,
只要保证抽象方法所在的类是抽象类,即可。

这样没有抽象方法的抽象类,也不能直接创建对象,在一些特殊场景下有用途(适配器模式)。

3、接口

1. 接口定义

接口就是多个类的公共规范。
接口是一种引用数据类型,最重要的内容就是其中的:抽象方法。


//如何定义一个接口的格式:
public interface 接口名称 {// 接口内容
}

备注:换成了关键字interface之后,编译生成的字节码文件仍然是:.java --> .class。

如果是Java 7,那么接口中可以包含的内容有:
1.常量
2.抽象方法

如果是Java 8,还可以额外包含有:
3.默认方法
4.静态方法

如果是Java 9,还可以额外包含有:
5.私有方法

在任何版本的Java中,接口都能定义抽象方法。
格式:
public abstract 返回值类型 方法名称(参数列表);

注意事项:

  1. 接口当中的抽象方法,修饰符必须是两个固定的关键字:public abstract
  2. 这两个关键字修饰符,可以选择性地省略。
  3. 方法的三要素,可以随意定义。
public interface MyInterfaceAbstract {// 这是一个抽象方法public abstract void methodAbs1();// 这也是抽象方法abstract void methodAbs2();// 这也是抽象方法public void methodAbs3();// 这也是抽象方法void methodAbs4();}

2. 接口默认方法

从Java 8开始,接口里允许定义默认方法。
格式:
public default 返回值类型 方法名称(参数列表) {
方法体
}
备注:接口当中的默认方法,可以解决接口升级的问题。即该接口新增一个方法时,若定义为default,则不影响已经实现该接口的实现类,又能完成升级接口。

public interface MyInterfaceDefault {// 抽象方法public abstract void methodAbs();// 新添加了一个抽象方法// public abstract void methodAbs2();// 新添加的方法,改成默认方法public default void methodDefault() {System.out.println("这是新添加的默认方法");}}

3. 接口静态方法

从Java 8开始,接口当中允许定义静态方法。
格式:
public static 返回值类型 方法名称(参数列表) {
方法体
}
提示:就是将abstract或者default换成static即可,带上方法体。

接口静态方法:

public interface MyInterfaceStatic {public static void methodStatic() {System.out.println("这是接口的静态方法!");}}

接口实现类:

public class MyInterfaceStaticImpl implements MyInterfaceStatic {}

3. 私有方法

问题描述:
我们需要抽取一个共有方法,用来解决两个默认方法之间重复代码的问题。
但是这个共有方法不应该让实现类使用,应该是私有化的。

解决方案:
从Java 9开始,接口当中允许定义私有方法。

  1. 普通私有方法,解决多个默认方法之间重复代码问题
    格式:
    private 返回值类型 方法名称(参数列表) {
    方法体
    }
  2. 静态私有方法,解决多个静态方法之间重复代码问题
    格式:
    private static 返回值类型 方法名称(参数列表) {
    方法体
    }
public interface MyInterfacePrivateA {public default void methodDefault1() {System.out.println("默认方法1");methodCommon();}public default void methodDefault2() {System.out.println("默认方法2");methodCommon();}private void methodCommon() {System.out.println("AAA");System.out.println("BBB");System.out.println("CCC");}}

4.接口常量

接口当中也可以定义“成员变量”,但是必须使用public static final三个关键字进行修饰。
从效果上看,这其实就是接口的【常量】。
格式:
public static final 数据类型 常量名称 = 数据值;
备注:
一旦使用final关键字进行修饰,说明不可改变。

注意事项:

  1. 接口当中的常量,可以省略public static final,注意:不写也照样是这样。
  2. 接口当中的常量,必须进行赋值;不能不赋值。
  3. 接口中常量的名称,使用完全大写的字母,用下划线进行分隔。(推荐命名规则)
public interface MyInterfaceConst {// 这其实就是一个常量,一旦赋值,不可以修改public static final int NUM_OF_MY_CLASS = 12;}
 public static void main(String[] args) {// 访问接口当中的常量System.out.println(MyInterfaceConst.NUM_OF_MY_CLASS);}

4.接口多继承

  1. 类与类之间是单继承的。直接父类只有一个。
  2. 类与接口之间是多实现的。一个类可以实现多个接口。
  3. 接口与接口之间是多继承的。

注意事项:

  1. 多个父接口当中的抽象方法如果重复,没关系。
  2. 多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,【而且带着default关键字】。
public interface MyInterfaceA {public abstract void methodA();public abstract void methodCommon();public default void methodDefault() {System.out.println("AAA");}}
public interface MyInterfaceB {public abstract void methodB();public abstract void methodCommon();public default void methodDefault() {System.out.println("BBB");}}
/*
这个子接口当中有几个方法?答:4个。
methodA 来源于接口A
methodB 来源于接口B
methodCommon 同时来源于接口A和B
method 来源于我自己*/
public interface MyInterface extends MyInterfaceA, MyInterfaceB {public abstract void method();@Overridepublic default void methodDefault() {}
}
public class MyInterfaceImpl implements MyInterface {@Overridepublic void method() {}@Overridepublic void methodA() {}@Overridepublic void methodB() {}@Overridepublic void methodCommon() {}
}

4、多态

多态:指对象有多种形态
代码当中体现多态性,其实就是一句话:父类引用指向子类对象
格式:
父类名称 对象名 = new 子类名称();
或者:
接口名称 对象名 = new 实现类名称();

1. 访问成员变量

访问成员变量的两种方式:

  1. 直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找。
  2. 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找。
public class Fu /*extends Object*/ {int num = 10;public void showNum() {System.out.println(num);}public void method() {System.out.println("父类方法");}public void methodFu() {System.out.println("父类特有方法");}}
public class Zi extends Fu {int num = 20;int age = 16;@Overridepublic void showNum() {System.out.println(num);}@Overridepublic void method() {System.out.println("子类方法");}public void methodZi() {System.out.println("子类特有方法");}
}
    public static void main(String[] args) {// 使用多态的写法,父类引用指向子类对象Fu obj = new Zi();System.out.println(obj.num); // 父:10
//        System.out.println(obj.age); // 错误写法!System.out.println("=============");// 子类没有覆盖重写,就是父:10// 子类如果覆盖重写,就是子:20obj.showNum();}

2. 访问成员方法
在多态的代码当中,成员方法的访问规则是:
看new的是谁,就优先用谁,没有则向上找。

口诀:编译看左边,运行看右边。

对比一下:
成员变量:编译看左边,运行还看左边。
成员方法:编译看左边,运行看右边。

    public static void main(String[] args) {Fu obj = new Zi(); // 多态obj.method(); // 父子都有,优先用子obj.methodFu(); // 子类没有,父类有,向上找到父类// 编译看左边,左边是Fu,Fu当中没有methodZi方法,所以编译报错。
//        obj.methodZi(); // 错误写法!}

3. 对象的向上转型及向下转型
其实就是多态的写法:
格式:父类名称 对象名 = new 子类名称()
含义:右侧创建一个子类对象,把它当做父类看待使用

public abstract class Animal {public abstract void eat();}
public class Cat extends Animal {@Overridepublic void eat() {System.out.println("猫吃鱼");}// 子类特有方法public void catchMouse() {System.out.println("猫抓老鼠");}
}
public class Dog extends Animal {@Overridepublic void eat() {System.out.println("狗吃SHIT");}public void watchHouse() {System.out.println("狗看家");}
}

向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端:
对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。

解决方案:用对象的向下转型【还原】。
对象向下转型,类似强制类型转换

public class Demo01Main {public static void main(String[] args) {// 对象的向上转型,就是:父类引用指向之类对象。Animal animal = new Cat(); // 本来创建的时候是一只猫animal.eat(); // 猫吃鱼//        animal.catchMouse(); // 错误写法!// 向下转型,进行“还原”动作Cat cat = (Cat) animal;cat.catchMouse(); // 猫抓老鼠// 下面是错误的向下转型// 本来new的时候是一只猫,现在非要当做狗// 错误写法!编译不会报错,但是运行会出现异常:// java.lang.ClassCastException,类转换异常Dog dog = (Dog) animal;}
}

4. Instanceof

如何才能知道一个父类引用的对象,本来是什么子类?
格式:
对象 instanceof 类名称
这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例。

    public static void main(String[] args) {Animal animal = new Dog(); // 本来是一只狗animal.eat(); // 狗吃SHIT// 如果希望掉用子类特有方法,需要向下转型// 判断一下父类引用animal本来是不是Dogif (animal instanceof Dog) {Dog dog = (Dog) animal;dog.watchHouse();}// 判断一下animal本来是不是Catif (animal instanceof Cat) {Cat cat = (Cat) animal;cat.catchMouse();}giveMeAPet(new Dog());}public static void giveMeAPet(Animal animal) {if (animal instanceof Dog) {Dog dog = (Dog) animal;dog.watchHouse();}if (animal instanceof Cat) {Cat cat = (Cat) animal;cat.catchMouse();}}

【Java】基础02相关推荐

  1. Java基础-02(基础语法)

    Java基础-02(基础语法) 一 注释 加粗样式 注释用来解释和说明程序的文字,注释是不会被执行的. 1.1单行注释 //这是一条单行注释 public int i; 1.2多行注释 /* 这是 * ...

  2. java基础-02数据类型

    基本类型 整数 byte byte 数据类型是8位.有符号的,以二进制补码表示的整数 最小值是 -128(-2^7) 最大值是 127(2^7-1) 默认值是 0 byte 类型用在大型数组中节约空间 ...

  3. Java基础02 方法与数据成员

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在Java基础01 从HelloWorld到面向对象,我们初步了解了对象(obje ...

  4. Java基础02:符号、数据转换

    1 注释.标识符.关键字 1.1 注释 Java中有三种: 单行注释: //注释内容 多行注释: /* 注释内容 */ 文档注释: /** 注释内容 / 注释修改 Editor编辑器 Color Sc ...

  5. Java基础02 面向对象

    文章目录 01 面向对象基础 1.设计对象并使用 1.1 类和对象 1.2 类的几个补充注意事项 2.封装 2.1 封装的概念 2.2 private关键字 3.this关键字 3.1 就近原则 3. ...

  6. Java基础02 位运算符<<、>>

    题:如何快速计算2的3次方?(利用位运算符) 答:和二进制打交道,效率高 public class data {public static void main(String[] args) {Syst ...

  7. Java/Android基础-02

    Java基础-02 概念 面向对象编程 将某一类事物抽象化,确定如何操作数据然后再考虑如何操作数据.然后再考虑下如何组织数据 特点 属性: 用来描述对象的数据元素称为对象的属性. 方法: 对象的属性进 ...

  8. 第一阶段>>>Java基础进阶 OOP/Reflect/注解/IO流/API核心

    目录 >>>java基础01-结构以及类型 >>>java基础02-初识数组 >>>java基础03-面向对象OOP >>>ja ...

  9. Java基础知识第一章

    Java基础01:注释 注释不会被执行,是给我们写代码的人看的,书写注释是一个非常好的习惯,平时写代码一定要注意规范 注释的种类 单行注释:一般在最前面加上// public class Hello{ ...

  10. 【狂神说Java笔记】Java基础

    Java基础01:注释 关闭 idea 后再次打开,默认打开上一次关闭时的项目 新建空项目 File --> New --> Project... Empty Project --> ...

最新文章

  1. Linux服务器默认建立的LVM逻辑卷磁盘空间分配不合理,根目录不够用,如何缩减和扩展逻辑卷?...
  2. Linux Kernel TCP/IP Stack — L4 Layer
  3. PHP-计算表单提交的数据
  4. linux启动java包脚本
  5. 用好href的target, base href
  6. 视觉SLAM笔记(55) 位姿图
  7. python一个星期可以入门吗_Python一星期入门第6篇: 模块和包
  8. 走出海量数据及访问量压力困境
  9. eclipse远程调试两种模式
  10. Windows桌面软件美化界面:分享著名的VC++ DirectUI/duilib/SOUI/REDM,IMGUI和C#开源界面库
  11. body与html 会有间隙,css – thead和tbody之间的间距
  12. 什么是 Web 3.0?|互联网的下一波浪潮解释
  13. alipay.trade.app.pay
  14. [从零学习汇编语言] - BX寄存器与loop指令
  15. 备案不用关闭网站的9种技巧
  16. 定位教程3---固定相机,先拍后抓
  17. 2020 物联网架构成长之路-物联网架构小结
  18. python模块化编程 pdf_模块化编程ModularProgramming-GitHub.PDF
  19. 科大讯飞语音识别技术实(yuan)战(ma)小结
  20. kali 2019.4安装微信及其他配置

热门文章

  1. “功夫之王”李小龙的16堂励志课
  2. 【跨年首秀】Python浪漫烟花秀带你完美结局2022
  3. 【高清】人体血管解剖图
  4. 企业信息化要解决的难题
  5. 杠杆炒股怎么样平仓?
  6. 许昌学院计算机类选修课,计算机公共选修课分类教学研究
  7. 实习生转正难 吗
  8. 光伏发电物联网数字化解决方案
  9. Ubuntu_Ubuntu下的PDF相关工具
  10. python 对象树