4.方法操作实例变量 对象的行为

news2024/11/26 19:15:42

4.1 操作对象状态的方法

同一类型的每个对象能够有不同的方法行为,任一类的每个实例都带有相同的方法,但是方法可以根据实例变量的值来表现不同的行为。

play()会播放title值表示的歌曲,调用某个实例的play()可能会播放“Politik”而另一个会播放“Darkstar”,然而方法却是相同的

void play() {

        soundPlayer,playSound(title);

}

Song t2 = new Song();

t2.setArtist("Travis");

t2.SetTitle("Sing");

Song s3 = new Song();

s3.setArtist("Sex Pistols");

s3.setTitle("My Way");

小型犬的叫声与大型犬不同

Dog类中的bark()方法会用size实例变量来决定使用哪一种声音

class Dog {
    int size;
    String name;

    void bark() {
        if (size > 60) {
            System.out.println("Woof! Woof!");
        } else if (size > 14) {
            System.out.println("Ruff! Ruff!");
        } else {
            System.out.println("Yip! Yip!");
        }
    }
}
class DogTestDrive {
    public static void main(String[] args) {
        Dog one = new Dog();
        one.size = 70;
        Dog two = new Dog();
        two.size = 8;
        Dog three = new Dog();
        three.size = 35;

        one.bark();
        two.bark();
        three.bark();
    }
}

4.2 方法参数与返回类型

可以传值给方法

方法会运用形参(parameter)。调用的一方会传入实参(argument)。
实参是传给方法的值。当它传入方法后就成了形参。参数跟局部(local)变量是一样的。它有类型与名称,可以在方法内运用。
重点是:如果某个方法需要参数,你就一定得传东西给它。那个东西得是适当类型的值。

1.调用Dog上的bark()方法,并传入“3”这个值(作为此方法的参数)

2.以int类型表示的值3会传递给bark()

3.此值会传给numOfBarks这个参数(int类型的变量)

4.把numOfBarks当作一般的变量使用

可以从方法中取返回值

方法可以有返回值。每个方法都声明返回的类型,但目前我们都是把方法设成返回void类型,这代表并没有返回任何东西。
void go() {

}
但我们可以声明一个方法,回传给调用方指定的类型值

int giveSecret() {

        return 42;

}
如果你将一个方法声明有返回值,你就必须返回所
声明类型的值! (或是与声明类型兼容的值)

可以向方法中传入一个以上的参数

方法可以有多个参数。在声明的时候要用逗号分开,传入的时候也是用逗号分开。最重要的是,如果方法有参数,一定要以正确数量、类型和顺序来传递参数。

4.3 值传递

Java是通过值传递的,也就是说通过拷贝传递

1.声明一个int类型的变量并赋值为7。代表7的字节组合会被放进称为x的变量

2.声明一个有int参数的方法,参数名称为z

3.以x为参数传入go()方法中。x的字节组合会被拷贝并装进z中

4.在方法中改变z的值。此时z的值不会改变,传给z的只是个拷贝

方法无法改变调用方所传入的参数

4.4 Getters与Setters

运用参数与返回类型

Getter与Setter。如果要很正式地讨论,你会称他们为Accessor与Mutator。不过这样只是更饶舌而已,由于Getter与Getter较为符合Java的命名习惯,所以我们接下来都会这么叫它们。
Getter与Setter可让你执行get与set。Getter的目的只有一个,就是返回实例变量的值。毫无意外的,Setter的目的就是要取用一个参数来设定实例变量的值。
 

public class ElectricGuitar {
    
    String brand;
    int numOfPickups;
    boolean rockStarUsesIt;
    
    String getBrand() {
        return brand;
    }
    void setBrand(String aBrand) {
        brand = aBrand;
    }
    int getNumOfPickups() {
        return numOfPickups;
    }
    void setNumOfPickups(int num) {
        numOfPickups = num;
    }
    boolean getRockStarUsesIt() {
        return rockStarUsesIt;
    }
    void setRockStarUsesIt(boolean yesOrNo) {
        rockStarUsesIt = yesOrNo;
    }
}

4.5 封装(Encapsulation)

不封装可能会很难堪

在此之前我们已经犯了一个在面向对象界最糟糕的错误
泄露资料!
我们并没有注意到数据会被全世界的人看到,甚至还可以被改动。
你可能经历过暴露出实例变量的不愉快感觉。
暴露的意思是可通过圆点运算符来存取,像是:
tehCat.height = 27;
你可以把这件事情看做是直接通过远程控制修改Cat的实例变量。若远程控制落入不当之人的手上,变量就可能会成为杀伤力强大的武器。因为你无法防止下面的操作:
theCat.height =0; //千万不能让这种事情发生
这一定会很糟糕.

我们需要创建Setter这个方法给所有的实例变量,并寻求某种方法强制其他程序都必须通过Setter来设定变量而不是直接的存取。

数据隐藏

要将程序的实现从不良数据改成可以保护数据且让你还能修改数据的方式是很简单的。所以要如何隐藏数据呢?答案是使用公有与私有这两个存取修饰符(access modifier)。

封装的基本原则:将你的实例变量标记为私有的,并提供公有的getter与setter来控制存取动作。或许在你有了更多的Java设计与编写经验之后会有些许不同的做法,但是目前这种做法可以维持住安全性。

将实例变量标记为private。
将getters与setters标记为public。

封装GoodDog

public class GoodDog {
    private int size;

    public int getSize() {
        return size;
    }
    public void setSize(int s) {
        size = s;
    }

    void bark() {
        if (size > 60) {
            System.out.println("Woof! Woof!");
        } else if (size > 14) {
            System.out.println("Ruff! Ruff!");
        } else {
            System.out.println("Yip! Yip!");
        }
    }
}
public class GoodDogTestDrive {
    public static void main(String[] args) {
        GoodDog one = new GoodDog();
        one.setSize(70);
        GoodDog two = new GoodDog();
        two.setSize(8);
        System.out.println("Dog one: " + one.getSize());
        System.out.println("Dog two: " + two.getSize());
        one.bark();
        two.bark();
    }
}

 任何有值可以被运用到的地方,都可用调用方法的方式来取得该类型的值

int x = 3 + 24;

int x = 3 + one.getSize();

数组中的对象就如同其他的对象一样,唯一的差别就
是如何取得而已。换言之,不同处在于你如何取得遥
控器。让我们先来尝试调用数组中的Dog对象。

4.6 数组中的引用

数组中对象的行为

数组中的对象就如同其他的对象一样,唯一的差别就
是如何取得而已。换言之,不同处在于你如何取得遥
控器。让我们先来尝试调用数组中的Dog对象。

1.声明一个装载7个Dog引用的Dog数组

Dog[] pets;

pets = new Dog[7];

2.创建两个Dog对象并赋值为数组的前两项元素

pets[0] = new Dog();

pets[1] = new Dog();

3.调用这两个Dog对象的方法

pets[0].setSize(30);

int x = pets[0].getSize();

pets[1].setSize(8);

声明与初始化实例变量

你已经知道变量的声明至少需要名称与类型:
int size;
String name;
并且你也知道可以同时初始化-(赋值)变量:
int size = 420;
String name ="Donny”;
但如果你没有初始实例变量时,调用getter会发生什么事?也就是说实例变量在初始之前的值是什么?

实例变量永远都会有默认值,若没有明确的赋值给实力并不了,或者没有调用setter,实例变量还是会有值

integers   0

floating points   0.0

booleans   false

reference   null

null代表没有操作对象的远程控制,是个引用而不是对象

实例变量与局部变量之间的差别

1.实例变量是声明在类内而不是方法中

class Horse {

        private double height = 15.2;

        private String bread;

        // more code...

}

2.局部变量是声明在方法中的

class AddThing {

        int a;

        int b = 12;

        public int add() {

                int total = a + b;

                return total;

        }

}

3.局部变量在使用前必须初始化

class Foo {

        public void go() {

                int x;

                int z = x + 3; //无法编译

        }

}

局部变量没有默认值,若在变量被初始化前就要使用的话,编译器会显示错误

变量的比较

有时你需要知道两个primitive主数据类型是否相等。很简单,只要使用==这个运算符就可以。有时你想要知道两个引用变量是否引用到堆上的同一个对象。这也很容易,也是使用==运算符。但有时你会需要知道两个对象是否真的相等。此时你就得使用equals()这个方法。相等的意义要视对象的类型而定。举例来说,如果两个不同的String带有相同的字符,它们在涵义上是相等的。但对Dog来说,你认为尺寸大小或名字一样的Dog是相等的吗?所以说是否被视为相等要看对象类型而定。我们会在后面的章节继续探讨对象相等性的部分,但现在我们要知道的是==只用来比对两个变量的字节组合,实质所表示的意义则不重要。字节组合要么就是相等,要么就是不相等。

使用==来比对primitive主数据类型

这个运算式可以用来比较任何类型的两个变量,它只是比较其中的字节组合

int a = 3;

byte b = 3;

if (a == b) {// true}

使用==来判别两个引用是否都指向同一对象

这只是在比较字节组合的模样。此规则适用于引用与primitive主数据类
型。因此==运算符对参照相同对象的引用变量会返回值。在此情况下我们还是无
法得知字节组合的样式,但可以确定的是所参照的相同的对象。

Foo a = new Foo();

Foo b = new Foo();

Foo c = a;

if (a == b) {// false}

if (a == c) {// true}

if (b == c) {// false}

使用==来比较两个primitive主数据类型,或者判断两个引用是否引用同一个对象。
使用equals()来判断两个对象是否在意义上相等。
(像是两个String对象是否带有相同的字节组合)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1070531.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第三章 Android 开发从入门到实战--简单控件

文章目录 1.文本显示1.1设置文本的内容1.2设置文本字体大小1.3设置文本的颜色 2.视图基础2.1设置视图的宽高2.2设置视图的间距2.3设置视图的对齐方式 3.常用布局3.1线性布局LinearLayout3.2相对布局RelativeLayout3.3网格布局GridLayout3.4滚动视图ScrollView 4.按钮触控4.1But…

集线器、交换机、路由器是如何转发包的

集线器、交换机、路由器是如何转发包的 集线器交换机MAC地址表的维护 路由器路由表中的信息路由器的包接收操作查询路由表确定输出端口找不到匹配路由时选择默认路由包的有效期通过分片功能拆分大网络包路由器发送操作中的一些特点 参考文档 集线器 集线器是一层(物…

异常:找不到匹配的key exchange算法

目录 问题描述原因分析解决方案 问题描述 PC 操作系统:Windows 10 企业版 LTSC PC 异常软件:XshellPortable 4(Build 0127) PC 正常软件:PuTTY Release 0.74、MobaXterm_Personal_23.1 服务器操作系统:OpenEuler 22.03 (LTS-SP2)…

【数据结构-二叉树 九】【树的子结构】:树的子结构

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【子结构】,使用【二叉树】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为&…

Qt单一应用实例判断

原本项目中使用QSharedMemory的方法来判断当前是否已存在运行的实例,但在MacOS上,当程序异常崩溃后,QSharedMemory没有被正常销毁,导致应用程序无法再次被打开。 对此,Qt assistant中有相关说明: 摘抄 qt-s…

Linux防火墙之firewalld

iptables与firewalld的联系 netfilter 位于Linux内核中的包过滤功能体系 称为Linux防火墙的“内核态” Firewalld/iptables CentOS7默认的管理防火墙规则的工具(Firewalld) 称为Linux防火墙的“用户态” iptables与firewalld的区别 iptables主要是基…

Spring的beanName生成器AnnotationBeanNameGenerator

博主介绍:✌全网粉丝4W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…

软件设计原则 1小时系列 (C++版)

文章目录 前言基本概念 Design Principles⭐单一职责原则(SRP) Single Responsibility PrincipleCode ⭐里氏替换原则(LSP) Liskov Substitution PrincipleCode ⭐开闭原则(OCP) Open Closed PrincipleCode ⭐依赖倒置原则(DIP) Dependency Inversion PrincipleCode ⭐接口隔离…

tailscale自建headscale和derp中继

tailscale自建headscale和derp中继 Tailscale 官方的 DERP 中继服务器全部在境外,在国内的网络环境中不一定能稳定连接,所以有必要建立自己的 DERP 服务器的。 准备工作: 需要有自己的云服务器,本示例为阿里云轻量服务器需要有…

Tasmota系统之外设配置

Tasmota系统之外设配置 🎈相关篇《ESP32/ESP8266在线刷写Sonoff Tasmota固件以及配置简要》🔖这里以ESP32配置DS18B20温度传感器和dht11温湿度传感器为例。 ✨如果想接特定型号的显示屏幕,需要下载指定的固件,目前官方所提供的固件…

剑指offer——JZ36 二叉搜索树与双向链表 解题思路与具体代码【C++】

一、题目描述与要求 二叉搜索树与双向链表_牛客题霸_牛客网 (nowcoder.com) 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示 数据范围:输入二叉树的节点数 0≤n≤1000,二叉树中每个节点的值 0≤val≤10…

“首站告捷 完美收官” | 风丘-EVM ASIA 2023精彩锦集

2023年9月19-21日,风丘携手德国IPETRONIK首次亮相马来西亚-EVM ASIA 2023——该地区第一大电动汽车、移动、制造和汽车零部件展览会,为大家呈现了在汽车测试、车辆诊断领域里专业的研发测试工具及创新解决方案,吸引了众多客户驻足洽谈。 无法…

SpringBoot-黑马程序员-学习笔记(一)

8.pom文件中的parent 我们使用普通maven项目导入依赖时,通常需要在导入依赖的时候指定版本号,而springboot项目不需要指定版本号,会根据当前springboot的版本来下载对应的最稳定的依赖版本。 点开pom文件会看到这个: 继承了一个…

WebGoat 靶场 JWT tokens 四 五 七关通关教程

文章目录 webGoat靶场第 四 关 修改投票数第五关第七关 你购买书,让Tom用户付钱 webGoat靶场 越权漏洞 将webgoat-server-8.1.0.jar复制到kali虚拟机中 sudo java -jar webgoat-server-8.1.0.jar --server.port8888解释: java:这是用于执行…

WebKit Inside: CSS 样式表的解析

CSS 全称为层叠样式表(Cascading Style Sheet),用来定义 HTML 文件最终显示的外观。 为了理解 CSS 的加载与解析,需要对 CSS 样式表的组成,尤其是 CSS Selector 有所了解,相关部分可以参看这里。 HTML 文件里面引入 CSS 样式表有 …

开启AI大模型时代|「Transformer论文精读」

论文地址: https://arxiv.org/pdf/1706.03762v5.pdf 代码地址: https://github.com/tensorflow/tensor2tensor.git 首发:微信公众号「魔方AI空间」,欢迎关注~ 大家好,我是魔方君~~ 近年来,人工智能技术发展迅猛&#…

解锁C语言结构体的力量(进阶)

引言:结构体是C语言中的重要部分,也是通向数据结构的一把“钥匙”,之前我们在这篇文章:http://t.csdnimg.cn/fBkBI已经简单的介绍了结构体的基础知识,本篇我们来更进一步的学习结构体。 目录 结构体的内存对齐 结构体…

二维码是啥?

大家好,我是tony4geek。 今天说下二维码。二维码我们每天都在使用。本文将深入探讨二维码的识别原理,了解其背后的技术和算法,以及它是如何将编码的信息解析成可读的文本或链接的。 一、二维码的基本结构 在探讨二维码的识别原理之前&…

这个国庆婚礼是一场接一场的到来,好幸福

爸妈参加了姐姐的游轮婚礼,爸爸诗兴大发作诗一首,虽然没能亲临,但我妈一直有小视频实时转播,新婚的幸福也已经感受到了!

自动驾驶学习笔记(二)——Apollo入门

#Apollo开发者# 学习课程的传送门如下,当您也准备学习自动驾驶时,可以和我一同前往: 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 Ubuntu Linux文件系统 Linux指令…