第四章.方法
//数据类型分为 基本数据类型 和 引用数据类型
**// 基本类型:将一个对象的实际值赋给另一个变量;在内存中存储的时一个基本类型值;**类型包括整型、浮点型、字符型、逻辑型。
例:
i=1;
j=2;
j = i;
就是将基本类型变量 j 的内容复制给基本类型变量 i。
**// 引用类型:将一个变量的引用赋给另一个变量;对应内存所存储的值是一个引用,是对象的存储地址;**类型包括数组、对象、接口。
例:
c1= new Circle(9); //引用c1,并赋予数值9
c2= new Circle(6); //引用c2,并赋予数值6
c2=c1; //将c1的引用赋予c2,此时c2数值为9
就是将c1的引用赋给c2,赋值之后,变量c2和c1指向同一个对象。这个时候c2以前的引用对象不再有用,因此,现在它就称为垃圾。垃圾会占用内存空间。Java运行系统会检测垃圾并自动回收它所占据的空间,这个过程称为垃圾回收。
【注意:如果你不再需要某个对象,可以显式地给该对象的引用变量赋值为null。 如果该对象没有被任何引用变量所引用,Java虚拟机会自动回收它所占据的空间。】
一. 面向对象语言:
1.封装性:一个对象将自己的数据和对这些数据的操作合理有效地封装在一起。
2.继承: 子类继承父类的属性和方法,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,
使得子类具有父类相同的属性和方法。
3.多态: 多个操作具有相同的名字,但各自接受的消息类型必须不同;
同一个操作被不同类型的对象调用时可能产生不同的行为。
二.类:
class (类) //类的声明部分
{ //类体分为 “变量的声明” 和 “方法的定义”
类体 //变量的声明:用来存储属性的值(体现对象的属性)
//成员变量:即 类体中的 变量声明 部分所声明的变量,又称域变量。
}
1.成员变量的类型可以是Java中的任何一种数据类型。
2.成员变量在整个类内都有效。
3.成员变量一行只声明一个变量。
1.构造方法:
方法可以对类中声明的变量进行操作,即一段用来完成特定功能的代码片段。
分为:方法头和方法体。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cLPP29H3-1606661502552)(C:\Users\Administrator\Desktop\笔记图\QQ浏览器截图20201128105610.png)]
1.构造方法的名字必须与它所在的类的名字完全相同,而且没有类型;
2.一个类可以构造若干个方法,但这些方法必须参数不同。即参数的个数不同,或参数个数相同,但若干个参数的类型不同;
2.创建对象:
使用new运算符和类的构造方法为声明的对象分配对象,即创建对象。
1.创建对象包括对象的声明和为对象分配变量。
2.如果类中没有构造方法,系统会调用默认的构造方法,默认的构造方法没有参数,且方法体中没有语句。
package xiyouji;
class xiyoujirenwu{
float height,weight;
String head,ear;
void speak(String s){
head = "歪着头";
System.out.println(s);
}
}
public class Example4_1{
public static void main(String[] args){
xiyoujirenwu zhubajie;
//声明对象
zhubajie = new xiyoujirenwu();
//为对象分配变量height、weight、head、ear
}
}
- new运算符只能和类的构造方法进行运算,运算的结果是个16进制的数,这个数即对象的引用。
参数类型:
1.形参是定义方法的时候,该方法所携带的参数,是用来接收调用者传递的参数的,形参只在方法内部有效。
2.实参是你在调用方法的时候,给这个方法传递的参数值,实参在传递给别的方法之前是要被预先赋值的。
3.在函数调用过程中,形参的值发生改变,而实参的值不会发生改变。
4.在引用传递调用的机制中,实际上是将实参引用的地址传递给了形参,所以任何发生在形参上的改变也会发生在实参变量上。
//修饰符:例如public static //数据类型:例如int
//局部变量:即方法体中 变量声明 和 方法的参数 。
//局部变量只在方法内有效,而且与其声明的位置有关。
//局部变量因为没有默认值,所以必须初始化,进行赋值。
(1).如果局部变量的名字和成员变量的名字相同,那么成员变量被隐藏,即该成员变量在这个方法内暂时失效。
(2).因为该方法暂时隐藏了成员变量,如果想重新使用成员变量,必须使用关键字 this 。 //格式类似强制类型转换,不用加()。
参数传值 :
package Example;
class Computer{
int add(int x,int y){
return x+y;
}
}
public class Example4_6{
public static void main(String[] args){
Computer computer = new Computer();
int m = 100;
int n = 100;
int result = computer.add(m,n);
//调用了Computer方法,但参数不同,将m,n参数传递给x,y
//此时m,n为传递方,x,y为被传递者
//所以m,n为实参;x,y为形式参数
System.out.println(result);
//调用add方法,输出200
result = computer.add(100*m,100*n);
//重新传值,重新调用
System.out.println(result);
//输出20000
}
}
5.一个类声明的两个对象如果具有相同的引用(引用型变量),二者就具有完全相同的变量:
例:
package Example;
class Battery {
//Battery共声明了battery、nanfu两个对象
int Eamount;
//定义变量
Battery(int amount){
//方法被调用时,参数变量必须要有具体的值
Eamount = amount;
}
}
class Radio {
void radio(Battery battery){
//声明Battery类对象battery
battery.Eamount=battery.Eamount-10;
//为对象battery分配变量Eamount,并赋值
}
}
public class dianchi {
public static void main(String[] args) {
Battery nanfu = new Battery(100);
//创建对象nanfu,调用Battery方法,给参数赋值100
System.out.println("南孚电池的储电量是:"+nanfu.Eamount);
System.out.println("收音机开始使用南孚电池");
Radio r= new Radio();
//创建Radio类对象r
r.radio(nanfu);
//r调用方法radio,引用对象nanfu
//此时r同时引用了nanfu对象和battery对象---即引用类型参数的传值
System.out.println("目前南孚电池的储电量是:"+nanfu.Eamount);
}
}
命令行传参:
在运行程序时,给其传递消息。这要靠传递命令行参数给main()函数实现。
package DEMO;
public class Demo1{
public static void main(String[] args){
//参数(String[] args)的作用就是
//可以在main方法运行前将参数传入main方法中
for (int i=0;i<args.length;i++){
System.out.println("args["+i+"]:"+args[i]);
}
}
}
以下为包内程序的运行方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HzoIdTiW-1606661502555)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201128102603033.png)]
可变参数:
是指在声明办法时,不给出参数列表中,具体的从某项开始到最后一项参数的个数与名字。
//这些参数类型必须一致。
//可变参数可以用 “…” 表示若干个参数。(结构类似数组)
例:public void f (int … x) {…}
//(int … x )必须设置在方法头的最后一个参数,否则容易报错。
package DEMO;
public class Demo2 {
public static void main(String[] args){
//调用可变参数的方法
printMAX(32,3,4,5,6,57.7);
printMAX(new double[]{1,2,3,4});
}
public static void printMAX(double...numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0]; //排序
for (int i =1 ;i <numbers.length;i++) {
if (numbers[i]>result) {
//不断将数组中的最大值赋值给result
result = numbers[i];
}
}
System.out.println("The max value is "+result);
}
}
对象的组合:
一个类的成员变量可以是Java允许的任何数据类型,因此,一个类可以把某个对象作为自己的一个成员变量。也就是说,该类的对象将其他对象作为自己的组成部分。
1.当前对象可以随时更换所包含的对象,即对象与所包含的对象属于弱耦合关系。
//耦合指两个类之间的联系的紧密程度。弱耦合指存在间接关系,强耦合指存在直接关系。
package phone;
public class SIM{
long number;
//定义成员变量
SIM(long number){
//调用方法时,参数必须有具体的值
//定义局部变量,同时覆盖了成员变量
this.number = number;
//使用this函数,调用成员变量
}
long getNumber(){
System.out.println(number);
//主类中的参数传值最终返回这里
return number;
}
}
package phone;
public class MobileTelephone{
SIM sim;
//创建对象;使用SIM类创建一个对象sim,这个对象可以调用SIM类的方法
void setSIM(SIM card){
//构造方法,同时对象MobileTelephone组合对象SIM作为自己的成员变量
sim = card;
//对象组合,委托对象SIM 调用其方法
}
long lookNumber(){
return sim.getNumber();
//返回调用方法getNumber的对象sim---返回类SIM的方法
}
}
package phone;
public class Example4_9{
public static void main(String[] args){
SIM simone = new SIM(18855356115L);
//创建SIM类对象simone,并给number赋值
MobileTelephone mobile = new MobileTelephone();
mobile.setSIM(simone);
//mobile调用setSIM方法,并将simone引用的手机号赋值给变量card---赋值给sim
System.out.println("手机号码:"+mobile.lookNumber());
SIM simtwo = new SIM(18362072098L);
//重新创建了SIM对象,并simtwe引用的手机号赋值给变量card---赋值给sim
mobile.setSIM(simtwo);
System.out.println("手机号码:"+mobile.lookNumber());
}
}
实例成员与类变量:
在类体中声明成员变量时,用关键字static给与修饰的称作 类变量(也称static变量、静态变量) ,否则称作 实例变量 。
//实例变量与类变量的区别
1.不同对象的实例变量互不相同:
即改变一个对象的实例变量 不会影响 其他对象的实例变量。
实例变量仅仅是和相应的对象关联的变量。
对象的实例变量可以通过该对象访问,但不能使用类名访问。
2.所有对象共享类变量:
即改变 一个对象的类变量 会影响其他对象的 这个类变量。
3.通过类名直接访问类变量:
因为类变量是与类相关联的变量,也就是说,类变量与该类创建的所有对象相关联,牵一发而动全身。
类变量不仅可以直接通过类名访问,也可以通过某个对象访问。
例:
package Example;
class LADER {
double 上底,高;
//实例变量上底,高
static double 下底;
//类变量下底
void 设置上底(double a){
上底=a;
}
void 设置下底(double b){
下底=b;
}
double 获取上底(){
return 上底;
}
double 获取下底(){
return 下底;
}
}
public class Example4_10 {
public static void main(String[] args) {
LADER.下底=100;
//通过类名操作类变量
LADER laderOne = new LADER();
laderOne.设置上底(6);
System.out.println("laderOne的上底:"+laderOne.获取上底()); //laderOne的上底:6.0
System.out.println("laderOne的下底:"+laderOne.获取下底()); //laderOne的下底:100.0
laderOne.设置下底(16);
//类变量与该类创建的所有对象相关联,牵一发而动全身。
System.out.println("laderOne的上底:"+laderOne.获取上底()); //laderOne的上底:6.0
System.out.println("laderOne的下底:"+laderOne.获取下底()); //laderOne的下底:16.0
LADER laderTwe = new LADER();
laderTwe.设置上底(26);
System.out.println("laderTwe的上底:"+laderTwe.获取上底()); //laderTwe的上底:26.0
System.out.println("laderTwe的下底:"+laderTwe.获取下底()); //laderTwe的下底:16.0
laderTwe.设置下底(36);
System.out.println("laderTwe的上底:"+laderTwe.获取上底()); //laderTwe的上底:26.0
System.out.println("laderTwe的下底:"+laderTwe.获取下底()); //laderTwe的下底:36.0
System.out.println("laderOne的上底:"+laderOne.获取上底()); //laderOne的上底:6.0
System.out.println("laderOne的下底:"+laderOne.获取下底()); //laderOne的下底:36.0
}
}
//实例方法与类方法:方法类型前用关键字static给与修饰,为类方法(静态方法);不加static为实例方法。
1.对象调用实例方法:
实例方法可以被类创建的任何对象调用,但也只能通过对象来调用;
不仅可以操作实例变量,也可以操作类变量。
2.类名调用类方法:
类方法不仅可以被类创建的任何对象进行调用执行,也可以通过类名调用;
类方法不能操作实例变量,也不能调用实例方法。
//因为当开始运行程序,加载类时,在类创建对象之前,实例成员变量还没有分配内存,而且实例方法也没有入口地址。。
3.类方法不用创建对象就可以通过类名直接调用。
方法重载:
1.概念:一个类中可以有多个方法具有相同的名字,即使方法的返回类型不同(返回类型不同不影响重载),这些方法的参数必须不同。
(参数不同即参数的个数不同,或参数的个数相同,但某个参数对应的类型不同。)
2.原理:方法名称相同时,编译器会根据调用方法的参数个数、参数类型去逐个匹配,去选择对应的方法。
(如果匹配失败,则编译器报错)
package Example;
import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocationPerORB;
import java.util.Scanner;
class People {
float hello(int a,int b) {
//方法名称相同,但参数类型为双整型
return a + b;
}
float hello(int a,long b){
//方法名称相同,但参数类型为整型+长文本型
return a-b;
}
double hello(double a,int b){
//方法名称相同,但参数类型为浮点型+整型
return a*b;
}
}
public class Example4_12 {
public static void main(String[] args) {
People tom = new People();
System.out.println(tom.hello(10,20));
//根据参数变量的值判断,调用第一个,得30.0
System.out.println(tom.hello(20,10L));
//根据参数变量的值判断,调用第二个,得10.0
System.out.println(tom.hello(10.0,20));
//根据参数变量的值判断,调用第三个,得200.0
}
}
3.重载方法之间必须保证相互的参数不同,要小心出现错误调用。(小心参数的类型,double浮点型之类)
package Example;
class Circle{
double radius,area;
void setRadius(double r){
radius = r;
}
double getArea(){
area = 3.14*radius*radius;
return area;
}
}
class Tixing{
double above,bottom,height;
Tixing(double a,double b,double c){
above = a;
bottom = b;
height = c;
}
double getArea(){
return (above+bottom)*height/2;
}
}
class Student{
double ComputerArea(Circle c){
double area = c.getArea();
return area;
}
double ComputerArea(Tixing t){
double area = t.getArea();
return area;
}
}
public class Example4_13 {
public static void main(String[] args) {
Circle circle = new Circle();
circle.setRadius(24.12);
System.out.println("圆的面积:"+circle.getArea());//另一种输出方式
Student zhang = new Student();
//创建对象,方便之后判断方法
double result = zhang.ComputerArea(circle);
//ComputerArea方法,但对象为circle,参数为radius与area
System.out.println("圆的面积:"+result);
//选择Circle类的getArea方法,求得面积为1826.7716160000002
Tixing tixing = new Tixing(3,6,9);
System.out.println("梯形的面积:"+tixing.getArea());//另一种输出方式
result = zhang.ComputerArea(tixing);
//ComputerArea方法,但对象为tixing,参数为above、bottom与height
System.out.println("梯形的面积:"+result);
//选择Tixing类的getArea方法,求得面积为40.5
}
}
this关键字
this关键字可以出现在实例方法与构造方法中,但不能出现在类方法中。
//以为类方法可以通过类名直接调用,此时类中可能还没有对象。
-
this关键字出现在类的构造方法中时,表示正在使用该构造方法所创建的对象。
//即 this关键字出现在类的内部时:
package Example; public class Example4_14 { int leg,hand; String name; Example4_14(String s){ name=s; this.init(); } void init(){ leg=2; hand=2; System.out.println(name+"有"+hand+"只手"+leg+"条腿"); } public static void main(String[] args) { Example4_14 boshi = new Example4_14("布什"); //this函数就表示对象boshi //只是this在内部用,而boshi在外部用 } }
-
this关键字出现在实例方法中,this就表示正在调用该方法的当前对象。
//因为实例方法只能通过对象来调用,不能用类名来调用。
class A{
double x;//类的实例成员变量
static int y;//类的static成员变量
void f(){
this . x=100; //用this来调用成员变量
A . y=200; //用类名调用static变量
}
}
//通常情况下,可以省略this与类名,可以直接调用变量;
//但是当实例成员变量的名字与局部变量的名字相同时,不可省略。此时,this表示调用当前类的实例变量
包(package)
1.目的是为了有效区分名字相同的类。
2.包名格式:package 包名; //作为源文件的第一条语句。
3.如果设置了多重包名,例package tom.jiafei
//调用方式为C:java(目录)> java tom.jiafei.主类名
import语句:
用户可以使用import语句调用不在同一个包中的类。
java.lang:包含所有的基本语言类;
java.swing:包含抽象窗口工具集中的图形、文本、窗口GUI类;
java.io:包含所有的输入\输出类;
java.util:包含实用类;
java.sql:包含操作数据库的类;
java.net:包含所有实现网络功能的类;
如果要引入一个包中的全部类,则可以用通配符(*)来代替类名:
import java.util.*;
表示引入java.util包中所有的类:
import java.util.Date;
表示引入自定义包中的类:
import tom.jiafei.*;
访问权限:
所谓访问权限,即指对象是否能通过".“运算符操作自己的变量或通过”."运算符调用类中的方法。
//类中的实例方法总是可以调用该类中的实例变量和类变量。
//类方法总是可以操作该类中的类变量,与访问限制修饰符无关。
访问权限修饰符:
-
public - - :共有变量和公有方法。
//权限最高,可以在不同包中不同类中被访问。
-
不用public、private、protected修饰符修饰(即不加任何修饰符)的成员变量和成员方法:友好变量和友好方法。
//权限从上至下排在第二,只能在同一个包中使用,包括不能被别的包的子类继承。
-
protected - - :受保护的成员变量和受保护的方法。
//除了子类以外,在别的类中无法引用protected修饰的变量和方法。
-
private - - : 私有变量和私有方法。
//只能被当前类使用,不能被其他类拿出来使用。是定义某个权限最低的变量和方法的关键字。也无法被继承。
//其他类可以使用super关键字调用private变量和方法。
-
当子类和父类在同一个包下:
子类可以继承父类中不是private的变量和方法。
当子类和父类在不同包下:
子类只能继承protected和public的成员变量。
-
不能用protected和private修饰类。
"."运算符调用类中的方法。
//类中的实例方法总是可以调用该类中的实例变量和类变量。
//类方法总是可以操作该类中的类变量,与访问限制修饰符无关。
访问权限修饰符:
-
public - - :共有变量和公有方法。
//权限最高,可以在不同包中不同类中被访问。
-
不用public、private、protected修饰符修饰(即不加任何修饰符)的成员变量和成员方法:友好变量和友好方法。
//权限从上至下排在第二,只能在同一个包中使用,包括不能被别的包的子类继承。
-
protected - - :受保护的成员变量和受保护的方法。
//除了子类以外,在别的类中无法引用protected修饰的变量和方法。
-
private - - : 私有变量和私有方法。
//只能被当前类使用,不能被其他类拿出来使用。是定义某个权限最低的变量和方法的关键字。也无法被继承。
//其他类可以使用super关键字调用private变量和方法。
-
当子类和父类在同一个包下:
子类可以继承父类中不是private的变量和方法。
当子类和父类在不同包下:
子类只能继承protected和public的成员变量。
-
不能用protected和private修饰类。