类与对象以及类的继承

2023-05-16

类与对象以及类的继承

Java是一门面向对象的语编程言。世界上有众多对象,我们把具有相同属性和方法的对象归为一个类。因此,“类”便是Java代码中的基本单位。下面是对一些名词的解释。


类是一个模板,用来定义多个对象共同的属性和方法。比如:学生,手机,食物……
对象
对象就是所属类的一个实例。比如:学生张三,iPhone,米饭……
属性
属性就是对象的状态数据。
方法
方法是对象的行为。

我们如何来定义一个类呢?
格式:public class 类名{
}

在大括号中间,我们定义类的属性和方法。
比如下面这个程序

public class Outman {
	public String name;
	public int blood;
	public int reduce;

	public void kill(Monster m) {
		m.blood -= reduce;

		System.out.println(name + "正在攻击" + m.name + "," + m.name + "掉血" + reduce + ",剩余血量" + m.blood);

	}

}

注意:属性一般是数据,在定义时要注意它的数据类型,以及要判断是公有属性还是私有属性,其中公有属性的定义如上图,私有属性的定义将在下面讲继承时提到;
而定义方法的格式是:
public 返回值类型 方法名(参数类型 参数名,,){ 方法体…}
与C语言中定义函数很相似。

定义好类了之后,我们就要在主函数中调用其中的属性和方法了。首先要创建对象,因为是面向对象程序设计。创建对象的格式:
类名 对象名 = new 类名();
接着我们要做的是调用属性和方法。格式如下:
调用属性:对象名.属性名 = 值; (字符串要用双引号括起来,数字类的直接写)
调用方法:对象名.方法名(实参,,);
下面举一个例子

public class Qaz {
	public static void main(String[] args) {

		Outman ou = new Outman();
		ou.name = "奥特曼";
		ou.blood = 100;
		ou.reduce = 10;

		Monster mo = new Monster();
		mo.name = "小怪兽";
		mo.blood = 100;
		mo.reduce = 5;
		
		ou.kill(mo);
	}
}

由上面这个程序我们可以发现,”Outman类”和”Monster类”具有相同三种属性,”name”,”blood”,”reduce”.这意味着,在这两个类中,我们分别定义了这三种属性。很明显,相同的代码我们写了两次,为了减少代码的冗余,我们引入“继承”的概念。
顾名思义,在人的意识里,总是子辈继承父辈。在程序设计中也可以用到这个概念,子类可以继承父类的属性和方法,并且,每个子类只能有一个父类,而父类可以拥有多个子类,这也是符合我们人类的常理的。

先来看一个例子。

程序一

public class People {
	private String name;
	private int blood;
	private int reduce;

	public void setName(String n) {
		name = n;
	}
	public void setBlood(int n){
	   blood=n;
	
	}

	
	public void setReduce(int n){
		
		reduce=n;
	}
	public String getName() {
		return name;
	}
    public int getBlood(){
    	return blood;
    	
    }
    public int getReduce(){
    	
    	return reduce;
    }
}

程序二

public class Outman extends People {
	public void kill(Monster m) {
		int a = m.getBlood();
		int b = getReduce();
		m.setBlood(a - b);

		System.out.println(
				getName() + "正在攻击" + m.getName() + "," + m.getName() + "掉血" + getReduce() + ",剩余血量" + m.getBlood());

	}
}

我们可以来分析一下这两个程序的关系。在第一个程序中,我们定义了一个“People”类,并且定义了它的属性和方法。在前面我们讲类与对象时,定义过一个”Outman“类以及它的属性”name“,”blood“,”reduce“。这三个属性和我们现在定义的”People“类的属性一样的,于是我们可以采取”继承“的方式,在定义”Outman“类时,直接将”People“的属性继承过来。
于是有了第二个程序。
在定义”Outman”类时,直接在后面添加extends People,意味着继承了”People”类。
因此,我们可以总结出子类在继承父类时,如何定义的格式。
格式:public class 子类 extends 父类{
}

通过这样的格式,我们便能使子类继承到父类的属性和方法,也就不用再重新写一遍代码了。这样的好处是什么呢?在前面讲类与对象时,我们还定义了一个”Monster”类,也具有相同的属性和方法。于是,我们可以同样的方法让“Monster”类继承“People”类,减少了再定义一次属性的时间。如下:

public class Monster extends People {

	public void kill(Outman o) {
		int m = o.getBlood();
		int n = getReduce();

		o.setBlood(m - n);

		System.out.println(
				getName() + "正在攻击" + o.getName() + "," + o.getName() + "掉血" + getReduce() + ",剩余血量" + o.getBlood());

	}

}

我们再回到刚刚的程序一,讲一讲私有属性。
在Java中,子类是无法继承父类的私有属性的,因为类具有封装性。因此,我们在定义了父类的私有属性之后,要再定义一个方法,把属性初始化,相当于把私有属性变得公有(但实际上不是公有),使子类也可以继承父类的私有属性。当然,在后面使用相关属性时,应使用已经加上前缀的属性名,而不是直接使用。
有一点要注意的是,我们在初始化私有属性时返回类型为空,也就是在之后使用这个属性时,虽然不会报错但是无法输出值的。所以我们还要定义一个能够返回值的方法。下面讲一下两种方法的定义格式。
初始化属性——定义set方法:public void set属性名(数据类型 变量名){
属性名= 变量名;
}

返回属性值——定义get方法:public String get属性名(){
return 属性名;
}

注意:第一排的属性名要大写并且和set/get连在一起

我们在进行类的继承的时候,会继承到父类方法。可是,对于不同的子类,会进行的方法是不一样,所以我们不能一成不变地继承所有。我们要根据子类的个性特点进行方法的重写。
方法重写的规则是:1.有继承关系的两个类之间 2.返回值类型,方法名,参数类型(个数,顺序)完全一样
格式:public 返回值类型 方法名(参数类型 参数名,,){ 新的方法体…}

关于自动转型和强制转型
自动转型定义是将子类对象的类型定义为父类类型,也就是说子类可以自动转换成父类。
如下程序:

public class Manage{
      public static void main(String[] args){
              Student st = new UNStudent();
              st.setName("小花");
              st.study();
       
             System.out.println("名字:"+st.getName());
   }
}

我们可以清楚的看到,在第三行中,等号前面的类是父类,而等号后面的类是子类,前后类名不统一,可是也没有报错。这就是因为,UNStudent是Student的子类,它可以自动转换成父类。自动转型,有极大的好处。
先看下面这个程序段。

java.awt.FlowLayout flow = new java.awt.FlowLayout();
		jf.setLayout(flow);

		javax.swing.ImageIcon image = new javax.swing.ImageIcon("C:\\Users\\LLY\\Pictures\\Saved Pictures\\timg.jpg");
		javax.swing.JLabel jla = new javax.swing.JLabel(image);
		java.awt.Dimension dm = new java.awt.Dimension(777, 400);
		jla.setPreferredSize(dm);
		jf.add(jla);

		javax.swing.JTextField jtf1 = new javax.swing.JTextField();
		javax.swing.JTextField jtf2 = new javax.swing.JTextField();
		java.awt.Dimension dm1 = new java.awt.Dimension(700, 40);
		// java.awt.Dimension dm2=new java.awt.Dimension(300,30);
		jtf1.setPreferredSize(dm1);
		jtf2.setPreferredSize(dm1);
		javax.swing.JLabel jla1 = new javax.swing.JLabel("账号");
		jf.add(jla1);
		jf.add(jtf1);
		javax.swing.JLabel jla2 = new javax.swing.JLabel("密码");
		jf.add(jla2);
		jf.add(jtf2);

		javax.swing.JCheckBox jcb1 = new javax.swing.JCheckBox("记住密码");
		javax.swing.JCheckBox jcb2 = new javax.swing.JCheckBox("自动登录");
		jf.add(jcb1);
		jf.add(jcb2);

我们可以看到,在这个程序段中,add方法使用了许多次,却是在不同的类的对象中使用的。通过追溯,我们发现,add方法属于Component类,而众多使用add方法的类,都是Component的子类。也就是说,它们通过自动转型,变成了父类,也就可以调用add方法,不用再重新定义一个新方法了,这节省了时间。
子类可以自动转成父类,但父类不能自动转成子类。不过,如果需要用父类调用子类特有的方法,就需要将父类强制转型成子类。
格式:子类名 子类对象=(子类名)父类对象
转型好之后就可以使用子类对象来调用子类方法了。

关于接口类
在讲接口类之前,我们先来讲讲类的类型。第一个是普通的类类型,第二个是接口类型,第三个是介于普通类和接口类之间的抽象类。由于抽象类和普通类很相似,在这里就不多加赘述了。
接下来具体说一下接口类。
和普通的类一样,接口在定义时也拥有一个关键字,不过不是class,而是interface。
于是定义的格式是这样的:public interface 类名{
}

与一般类不同的是,这里大括号里的内容有所变化。
首先会定义静态常量。格式是:public static final 数据类型 属性名=初始值;
其中,“public static final”是默认的,不管写不写,在接口类中,都默认存在。也就是说,一旦给属性赋予初始值,这个值便不能再更改,也就相当于一个常量了。
然后会定义抽象方法。格式是:public abstract 返回值类型 方法名();
注意:抽象方法中是没有方法体的。
一般我们使用接口通过的方法都是接口的实现。也可以说是继承接口。不过我们在继承类是使用的是extends ,而实现接口使用的是implements。并且,一个子类只能继承一个父类,但可以实现多个接口。
格式:public class 子类 extends 父类 implements 接口类,接口类,,{}

由于在接口中我们定义的都是抽象方法,所以为了使用这些方法,我们在子类实现接口时,要实现(重写)接口中的所有抽象方法。这里的重写,和上面的方法重写是一样的,这里不再赘述。

最后讲讲我在写程序的过程中,遇到的困难和问题。
1.有时候,在方法比较复杂不好直接继承的时候,可以分别写两次代码。
2.在主函数调用属性和方法时,要注意一个特殊情况,就是私有属性的调用,是通过调用方法的方式。不要弄错格式了。
3.在进行属性值的比较、输出时,要使用具有返回值的方法,也就是get方法,而不是set方法。
4.如果调用的私有属性名太长,降低了可读性,可以定义一个变量来代替。格式如下:
类型 变量名=对象.方法();
当然,这个方法需要有返回值。这个变量的使用规则是,可以单独进行值的比较,如果要进行值的运算,需要在初始化方法中进行,这样运算才是有效的,值才会变。

以上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类与对象以及类的继承 的相关文章

随机推荐

  • 搭建ROS小车——下位机篇(基于arduino mega2560,L298N)

    ROS与arduino的通讯使用了ros arduino bridge xff0c 代码也是根据学校师兄的代码进行修改的 xff0c 师兄说直接烧录就可以使用了但我还是遇到了很多问题 xff0c Debug的很难受 xff0c 以下操作仅供
  • 树莓派入门操作及VNC显示 cannot currently show the desktop 解决方法

    新手入门 xff0c 装好了系统 xff0c ssh已经设置好了 插入SD卡 电源 绿灯闪烁代表正常开机 查树莓派IP xff0c 最快捷方法直接进入路由器后台配置界面 xff0c 查看ip地址 或者下载工具 xff1a advanced
  • 【Matlab】建立最优控制LQR控制器模型

    前言 之前做了有关于系统辨识以及配置极点来控制系统响应的相关内容 xff0c 那些相当于是打开了一个新世界的大门 xff0c 在此基础上 xff0c 一直想学习一下最优控制的相关内容 xff0c 并应用在项目上 xff0c 因此 xff0c
  • 人工智能算法公式中常见的数据符号的定义和解释?

    长期更新中 没有记录的希望大家留言补充 对数 xff1a xff08 log xff0c lg xff0c ln xff0c lb xff09 log log4 xff08 8 xff09 61 log4 xff08 4 2 xff09 6
  • 我的2014

    弹指间2014过去了 xff0c 在过去的一年里 xff0c 或许你收获了成功 xff0c 取得了令人瞩目的成绩 又或许你失意落魄 xff0c 躲在角落了自舔伤口 但这些都不重要 xff0c 重要的是今年是2015不是2014 新的一年里有
  • 51单片机实现串口偶校验

    1 STC单片机串口 2 PSW是一个8位寄存器 PSW的全称是Program Status Word xff0c 即程序状态字 奇偶标志位P 每执行一条汇编指令 xff0c 单片机都能根据A中1的个数的奇偶自动令P置位或清零 xff0c
  • SLAM十四讲第二版ch7位姿估计实践的编译问题

    在看ch7中遇到了g2o OptimizableGraph Vertex clone const 未定义的引用的问题 为了方便以后复现 xff0c 记录如下 我的环境配置 Pangolin 0 5 Opencv 3 4 16 cere 1
  • SLAM十四讲第二版ch6的未定义的引用问题

    在使用slam十四讲第二版做题的时候发现 xff0c ch6编译问题 xff0c 特此记录如下 make时遇到问题如下 xff1a 对 g2o OptimizableGraph Vertex clone const 未定义的引用 对 g2o
  • Ubuntu18.04配置ORB_SLAM3(ROS)

    一 安装ROS 建议按照官网操作 cn melodic Installation Ubuntu ROS Wiki http wiki ros org cn melodic Installation Ubuntu 二 安装eigen3 3 7
  • Semantic Visual Simultaneous Localization and Mapping: A Survey阅读笔记

    Abstract xff1a 通过语义和vslam结合可以很好解决动态和复杂环境中良好定位 首先回顾了语义vslam发展 xff0c 关注优势和差异 其次探讨了 xff1a 语义信息提取和关联 语义的应用和语义的优势然后收集分析了最先进的s
  • git上传到gitee的记录

    一 安装和配置 sudo apt get install git git config global user email 你的邮箱 git config global user name 64 你的昵称 二 上传 先在github或者gi
  • Burst Imaging for Light-Constrained Structure-From-Motion论文翻译记录

    准备开始2022ICRA的SLAM论文阅读记录 Abstract 在极低光照条件下拍摄的图像受噪声限制 xff0c 会导致现有的机器人视觉算法失效 在本文中 xff0c 我们开发了一种图像处理技术 xff0c 用于从弱光条件下采集的图像中辅
  • ROS常用指令

    非代码 一 创建工作空间 mkdir p catkin ws src cd catkin ws src catkin init workspace 二 创建功能包 cd workspace src catin create pkg name
  • 【Matlab】线性跟踪微分器

    线性跟踪微分器介绍 xff1a 线性跟踪微分器出自自抗扰控制ADRC xff0c 线性跟踪微分器有两个作用 xff0c 一是可以用来滤波 xff0c 而是可以用来求取输入的微分 这里有一篇文章可以推荐看看 xff1a https blog
  • FreeRTOS启动流程

    Reset Handler xff1a 芯片上电默认进Reset Handler SystemInit xff1a 初始化时钟及中断向量映射 main xff1a main函数入口 main xTaskCreate xff1a pvPort
  • 基于STM32F411使用SPI+DMA驱动LCD

    先看效果 F411CE 硬件SPI xff0b DMA驱动LCD 基于HAL库 其实HAL库我用不太习惯 xff0c 一直也是用的标准库 但HAL库确实是好上手一些 xff0c 就迅速创建一个新的template 这次就当尝试一下吧 xff
  • 动手深度学习-环境配置(手动安装,一步一步教你,有截图可看)

    一 xff1a 官网教程 这一部分对应了书中的第二讲 xff1a 预备知识部分 因为我是Windows用户 xff0c 所以这里先只讲Windows部分的安装过程 1 xff1a 第一步是根据操作系统下载并安装Miniconda xff0c
  • 机器学习算法原理与实践(三)、卡尔曼滤波器算法浅析及matlab实战

    协方差矩阵 状态协方差矩阵传递 状态协方差的更新 Matlab 实现 Matlab效果 测试代码 测试效果 原创 Liu LongPo 转载请注明出处 CSDN http blog csdn net llp1992 卡尔曼滤波器是一种利用线
  • Pixhawk之获取传感器数据并更新姿态

    博主 xff1a UAV 声明 xff1a 尊重版权 xff0c 转载请注明出处 原文地址 xff1a 联系方式 xff1a 595493514 64 qq com 技术交流QQ xff1a 595493514 read AHRS 是负责更
  • 类与对象以及类的继承

    类与对象以及类的继承 Java是一门面向对象的语编程言 世界上有众多对象 xff0c 我们把具有相同属性和方法的对象归为一个类 因此 xff0c 类 便是Java代码中的基本单位 下面是对一些名词的解释 类 类是一个模板 xff0c 用来定