目录

  • 阅前说明
  • 面向对象思想
    • 面向对象思想概述
  • 类和对象
    • 代码示例
    • 对象内存图
  • 继承
    • 概述
    • 定义
    • 优点
    • 格式
    • 代码示例
  • super和this
    • super和this的含义
    • 用法
  • 抽象类
    • 概述
    • 抽象类的使用格式
      • 抽象方法
      • 抽象类
      • 代码示例
    • 注意事项
  • 综合示例

阅前说明

本文根据个人理解以及学习记录撰写,如有不对或者理解不到之处请指正。

面向对象思想

面向对象思想概述

在谈类概念前,首先要说的是Java的特点——面向对象。对象泛指某种事物,这种事物具备属性行为。而面向对象思想是一种程序设计思想,开发者在这种思想的指引下,使用Java来设计和开发计算机程序。它强调的是通过调用对象的行为来实现功能,而不是自己去逐步完成。
以生活中的事情举例,洗衣服是我们要完成的程序,某某洗衣机是对象,它的属性可以是它的品牌,类型(滚筒还是立桶)等,功能则是洗衣。如果失去对象,完成洗衣服这个程序就需要我们用手一步步完成。

类和对象

什么是

类是一组相关属性行为的集合,类似于模板。它具有的属性和行为可以用来描述一类事物。比如,洗衣机是一个类,这三个字可以描述市面上所有的洗衣机,其中包括竖桶、滚筒、带烘干、不带烘干等等各种各样品牌的洗衣机。类是一类事物的描述,是抽象的。

什么是对象
对象是某一类事物的具体表现。它是一个类的实例,必然具备这个类的属性和行为。比如,狸花猫是猫的这个类的实例,它具备所有猫的属性和行为。对象是一类的事物的实例,是具体的。
由此可见,类是对象的模板,对象是类的实体

代码示例

public class Student {String name;//姓名int age;//年龄public void study(Student student) {System.out.println(name + "今年" + age + "岁,现在正在学习。");}public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}
public class DemoStudent {public static void main(String[] args) {Student stu1 = new Student();//无参构造Student stu2 = new Student("老八", 8);//全参构stu2.study(stu2);}
}运行结果:
老八今年8岁,现在正在学习

这里写了两段代码,分别为类和对象。其中student类的属性为name和age,方法是study。然后对象设置为某一个具体学生,并执行类中的方法。

对象内存图


在运行main方法前,方法区首先写入数据,里面保存的是.class相关数据。由图左边可以看出,一共有两个.class。一个叫phone.class,里面包含成员变量和成员方法,另一个是main方法的.class(图片显示不完整)。

在方法区写入数据之后,从main方法开始执行。所以,main方法进入栈空间(进栈或者叫压栈),开始执行第一条语句。第一条语句创建了一个对象,等号左边相当于一个局部变量,用来保存内容,而右边则是一个对象,此时在堆内存中开辟一块空间,这块空间的内容在方法区可以找到,包括了成员方法和成员变量。成员变量区域首先保存的是变量的默认值(不同类型的默认值不同),成员方法区域保存的则是方法的地址值。回到栈中,main方法中的成员变量p保存的是堆中对象的地址值。

接着执行下一条语句p.方法名()。首先根据p可以得到对象的地址值,然后找到对象,接着根据对象保存的地址值找到方法区中的成员方法xxx。想要运行这个成员方法,也需要进栈,在栈中开辟一个新空间。方法运行完成后再执行出栈操作从栈中消失。

最后main方法再次出现,执行下一条语句重复上述过程。(图片来自网络)

继承

概述

什么是继承
继承的概念出现在当多个类拥有相同的属性时,将这些共同的内容提取到一个单独的类中,那么这些拥有相同属性的类只需要继承这个单独的类就无需再定义这些相同的属性和行为。被继承的类称为父类,继承父类的类称为子类。
例如:动物作为一个单独类具有吃和睡这两种方法,那么凡是具有动物概念的生物都具有吃和睡这两种方法。

定义

继承:就是子类继承父类的属性和行为,使子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。

优点

  1. 提高代码的复用性
  2. 类与类之间产生了关系,是多态的前提。

格式

class 父类 { ... }
class 子类 extends 父类 { ... }

代码示例

/*
*  定义员工类Employee,做为父类* */
class Employee {String name; // 定义name属性// 定义员工的工作方法public void work() {System.out.println("正在尽心尽力地工作");}}/** 定义讲师类Teacher 继承 员工类Employee*/
class Teacher extends Employee {// 定义一个打印name的方法public void printName() {System.out.println("我是" + name);}
}/** 定义测试类*/
public class ExtendDemo01 {public static void main(String[] args) {// 创建一个讲师类对象Teacher t = new Teacher();// 为该员工类的name属性进行赋值t.name = "小明";// 调用该员工的printName()方法t.printName(); // name = 小明// 调用Teacher类继承来的work()方法t.work();  // 尽心尽力地工作}
}运行结果:
我是小明
正在尽心尽力地工作

上述代码可以看到,子类Teacher在继承父类Employee后享有其属性和方法,不需要单独创建就能使用。

当子类创建了相同的属性后,程序会优先使用子类中的变量。如果想要使用父类中的变量需要使用super关键字。
格式: super.父类变量名
同时,如果子类中出现和父类一样的成员方法,则子类中的方法会覆盖父类的方法,称为方法重写(Override)。如果想使用父类的成员方法同样需要使用super关键字。
格式: super.父类方法名
注意:

  1. 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
  2. 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。

补充: 一个子类只能有一个父类。

super和this

super和this的含义

  1. super:代表父类空间的存储空间标识(可以理解为父类的引用)
  2. this:代表当前对象的引用(是本类,可以理解为谁调用就是谁)

用法

  1. 访问成员:
    this.成员变量 ‐‐ 本类的
    super.成员变量 ‐‐ 父类的
    this.成员方法名( ) ‐‐ 本类的
    super.成员方法名( ) ‐‐ 父类的
  2. 访问构造方法
    this( ) ‐‐ 本类的构造方法
    super( ) ‐‐ 父类的构造方法

代码示例

/**  定义员工类Employee,做为父类* */
public class Employee {String name; // 定义name属性public Employee() {System.out.println("父类无参构造方法被使用");}public Employee(String name) {this();this.name = name;}// 定义员工的工作方法public void work() {System.out.println("正在尽心尽力地工作");}}
/** 定义讲师类Teacher 继承 员工类Employee*/
class Teacher extends Employee {String nicheng;//假设昵称不是共有属性public Teacher() {super();}public Teacher(String nicheng) {super(nicheng);this.nicheng = nicheng;}// 定义一个打印name的方法public void printName() {System.out.println("我是" + name);super.work();}
}
/*
* 测试用例
* */
public class Dmo {public static void main(String[] args) System.out.println("----创建一个子类空参对象----");Teacher t = new Teacher();//使用super()调用父类无参构造方法System.out.println("----创建一个子类有参对象----");Teacher t1 = new Teacher("小明");//使用super(参数)调用父类有参构造方法t1.printName();//使用了super.方法名调用父类的方法System.out.println("----创建一个父类有参对象----");Employee e = new Employee("小李");//使用this()调用本类的无参构造方法}
}运行结果:
----创建一个子类空参对象----
父类无参构造方法被使用
----创建一个子类有参对象----
父类无参构造方法被使用
我是小明
正在尽心尽力地工作
----创建一个父类有参对象----
父类无参构造方法被使

抽象类

概述

当子类重写并且不再使用父类中的方法时,那么父类中的方法只需要保留方法声明,删去方法主体。没有了方法体的方法被称为抽象方法。Java语法中规定,包含抽象方法的类称为抽象类
由此可见,抽象方法就是没有方法体的方法;抽象类就是包含抽象方法的类

抽象类的使用格式

抽象方法

使用 abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。
定义格式:

修饰符 abstract 返回值类型 方法名 (参数列表);

代码举例:

public abstract void run();

抽象类

如果一个类包含抽象方法,那么该类必须是抽象类。
定义格式

abstract class 类名字 { }

代码举例

public abstract class Animal { public abstract void run(); }

代码示例

如果创建了抽象类作为父类,那么继承抽象类的子类需要重写父类的所有抽象方法,否则,该子类也必须声明为抽象类,直到有子类实现父类的抽象方法。
示例:

/*
* 父类抽象类
* */
public abstract class Animal {public abstract void run();
}
/*
* 父类抽象类
* */
public abstract class Animal {public abstract void run();
}
/** 测试用例* */
public class Demo {public static void main(String[] args) {Cat cat = new Cat();cat.run();}
}运行结果:
奔涌吧,后猫

此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法

注意事项

关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  1. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的

理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。

  1. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设 计。

  1. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象 类

理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有 意义

综合示例

要求:

群主发普通红包。某群有多名成员,群主给成员发普通红包。普通红包的规则:

  1. 群主的一笔金额,从群主余额中扣除,分成n等份,让成员领取。
  2. 成员领取红包后,保存到成员余额中。

请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作。

/*
定义父类抽象类
*/
public class User {private String name;//身份private double leftMoney;//余额public User() {}public User(String name, double leftMoney) {this.name = name;this.leftMoney = leftMoney;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getLeftMoney() {return leftMoney;}public void setLeftMoney(double leftMoney) {this.leftMoney = leftMoney;}public void show(){System.out.println("姓名:" + getName() + ",余额" + getLeftMoney());}
}
/*
群主类
*/public class Manager extends User {public Manager() {//本类构造方法}public Manager(String name, double leftMoney) {//调用父类方法super(name, leftMoney);}public ArrayList<Double> send(double num, int count) {//创建一个存放每个红包的数组ArrayList<Double> list = new ArrayList<>();//判断红包金额是否大于余额if (num > super.getLeftMoney()) {System.out.println("金额不合法");return list;}super.setLeftMoney(getLeftMoney() - num);//创建随机红包金额Random rd = new Random();double n = 0;//用于存放随机金额for (int i = 0; i < count - 1; i++) {n = Math.random()*num;//范围在0~1.0之间  防止出现0n = Double.parseDouble(String.format("%.2f",n));//强转list.add(n);num = num - n;}num = Double.parseDouble(String.format("%.2f",num));//强转list.add(num);//存入最后的数字return list;}
}
/*
群员类
*/public class Member extends User {public Member() {}public Member(String name, double leftMoney) {super(name, leftMoney);}public void open(ArrayList<Double> list, String name) {//创建随机对象Random rd = new Random();
//        Double money = list.remove(rd.nextInt(list.size()));Double money = list.remove(0);System.out.println("恭喜" + name + "获得了" + money + "元")super.setLeftMoney(getLeftMoney() + money);}
}
/*
红包实现
*/public class TestHongbao {public static void main(String[] args) {//设置群主名称和余额Manager m = new Manager("one",100);//塞红包ArrayList<Double> money = m.send(80,3);//设置群员名称和余额Member me1 = new Member("two",50);Member me2 = new Member("three",50);Member me3 = new Member("four",50);//开红包me1.open(money,me1.getName());me2.open(money,me2.getName());me3.open(money,me3.getName());//显示余额m.show();me1.show();me2.show();me3.show();}
}运行结果:
恭喜two获得了3.17元
恭喜three获得了25.63元
恭喜four获得了51.2元
姓名:one,余额20.0
姓名:two,余额53.17
姓名:three,余额75.63
姓名:four,余额101.2

浅谈Java中类的相关内容相关推荐

  1. java 中的单元测试_浅谈Java 中的单元测试

    单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...

  2. java的byte php_java_浅谈java的byte数组的不同写法,(由于篇幅原因阐述的不够详 - phpStudy...

    浅谈java的byte数组的不同写法 (由于篇幅原因阐述的不够详细科学,不喜勿喷). 经常看到java中对byte数组的不同定义,粗略整理的一下: 一个字节(byte)=8位(bit),"b ...

  3. java bitset用途_浅谈Java BitSet使用场景和代码示例

    搜索热词 @H_502_0@一.什么是BitSet? @H_502_0@ 注:以下内容来自JDK API: @H_502_0@ BitSet类实现了一个按需增长的位向量.位Set的每一个组件都有一个b ...

  4. java方法区对象类型_浅谈Java内存区域与对象创建过程

    一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...

  5. java手动回收_浅谈java是如何做资源回收补救的

    学习java的过程,我们经常谈论一个对象的回收,尤其是资源类型,如果没有显示的关闭,对象就被回收了,说明出现了资源泄漏.java本身为了防止这种情况,做了一些担保的方式,确保可以让未关闭的资源合理回收 ...

  6. aba会导致问题_浅谈Java中ABA问题及避免

    本文主要研究的是关于Java中ABA问题及避免的相关内容,具体如下. 在<Java并发实战>一书的第15章中有一个用原子变量实现的并发栈,代码如下: public class Node { ...

  7. 浅谈JAVA程序破解(原创)

    浅谈JAVA程序破解 作者:舵手 申明:如转载请保证文章的完整性以及出处 最近对JAVA程序的破解比较感兴趣,拿几个行业软件练了一下手,略有心得,拿出来与菜鸟分享!注意只是一点心得, 本文并不涉及具体 ...

  8. java 线程aba,浅谈Java中ABA问题及避免,浅谈javaaba避免

    浅谈Java中ABA问题及避免,浅谈javaaba避免 本文主要研究的是关于Java中ABA问题及避免的相关内容,具体如下. 在<Java并发实战>一书的第15章中有一个用原子变量实现的并 ...

  9. 浅谈JAVA程序破解

    浅谈JAVA程序破解 http://www.blogjava.net/galaxyp/archive/2006/04/19/41833.html 作者:舵手 申明:如转载请保证文章的完整性以及出处 最 ...

最新文章

  1. 2021年大数据Kafka(八):Kafka如何保证数据不丢失
  2. sql中还在傻傻的手动添加创建人、创建时间?高级开发工程师不得不知的一个通用技巧!
  3. 台式计算机装电源线,完美:[机箱电源线的连接方法]如何选择台式机电源?组装台式计算机机箱的电源线连接方法图...
  4. CSS hack:针对IE6,IE7,IE8,IE9,firefox显示不同效果
  5. python 字符串 编码 解码_Python 字符串编解码研究
  6. Django简介以及安装
  7. powerDesigner生成excel版本的数据库文件
  8. 启程 一些高考后的想法
  9. Docker教程:镜像构建和自动镜像构建dockerfile
  10. 计算机存储溢出 是什么意思,数据溢出是什么意思
  11. 更新应用程序安卓apk时出现解析程序包时出现问题
  12. 清除电脑bios密码
  13. C# 游戏制作 | ✨ 简易文字小游戏
  14. 《好妈妈胜过好老师》书摘
  15. 【论文阅读】DenseCLIP: Language-Guided Dense Prediction with Context-Aware Prompting
  16. 7-1 树的同构 【已改正】
  17. 更进阶的实战效率、更准确的研究成果——欢迎参加材料计算PWmat进阶小组会
  18. repeat()方法
  19. 用Python让蔡徐坤在我的命令行里打篮球!| 附完整代码
  20. KeyBert、TextRank等九种本文关键词提取算法(KPE)原理及代码实现

热门文章

  1. 计算机汉字字形通常有两种字形编码,汉字字形编码有哪两种类型?各有什么特点?...
  2. 中学-知识与能力【6】
  3. easyuefi如何添加引导_UEFI怎么用 UEFI安全启动设置添加方法步骤图解
  4. 程序员是世界上最聪明、最具幽默感的一群人
  5. 金大侠的亲属与剑桥大学最厉害的三个学院
  6. 起始2021-01-15
  7. 计算机软考网络工程师 查询,软考网络工程师怎么查询报名是否成功?
  8. hadoop配置文件workers
  9. 字符串水题——相对分子质量
  10. oracle查询员工员工部门领导领导部门,oracle多表查询之经典面试题