自学Java第五章——《面向对象基础》
5.1 类与对象
1、类:一类具有相同特性的事物的抽象描述。
对象:类的一个个体,实例,具体的存在。
类是对象的设计模板。
2、如何声明类?
【修饰符】 class 类名{
成员列表:属性、方法、构造器、代码块、内部类
}
3、如何创建对象?
new 类名(); //匿名对象
类名 对象名 = new 类名(); //有名对象
5.2 类的成员之一:属性
1、如何声明属性?
【修饰符】 class 类名{
【修饰符】 数据类型 属性名; //属性有默认值
【修饰符】 数据类型 属性名 = 值; //属性有初始值
}
说明:属性的类型可以是Java的任意类型,包括基本数据类型、引用数据类型(类、接口、数组等)
总结:Java的数据类型
(1)基本数据类型
byte,short,int,long,float,double,char,boolean
(2)引用数据类型
①类:
例如:String、Student、Circle、System、Scanner、Math...
②接口:后面讲
③数组:
例如:int[],String[],char[],int[][]
int[] arr = new int[5];
这里把int[]看成数组类型,是一种引用数据类型,右边赋值的是一个数组的对象
元素的数据类型:int
数组的数据类型:int[]
2、如何为属性赋值?
(1)在声明属性时显式赋值
【修饰符】 class 类名{
【修饰符】 数据类型 属性名 = 值; //属性有初始值
}
代码示例:
class Student{
String name;
char gender = '男';//显式赋值
}
class TestStudent{
public static void main(String[] args){
Student s1 = new Student();
System.out.println("姓名:" + s1.name);//null
System.out.println("性别:" + s1.gender);//男
s1.name = "小薇";//修改属性的默认值
s1.gender = '女';//修改属性的初始值
System.out.println("姓名:" + s1.name);//小薇
System.out.println("性别:" + s1.gender);//女
Student s2 = new Student();
System.out.println("姓名:" + s2.name);//null
System.out.println("性别:" + s2.gender);//男
}
}
(2)创建对象之后赋值
【修饰符】 class 类名{
【修饰符】 数据类型 属性名; //属性有默认值
}
//创建对象
类名 对象名 = new 类名();
//为对象的属性赋值
对象名.属性名 = 值;
3、如何访问属性的值?
(1)在本类的方法中访问
示例代码:
class Circle{
double radius;
double getArea(){
return 3.14 * radius * radius;//直接访问
}
}
(2)在其他类的方法中访问
class Circle{
double radius;
}
class TestCircle{
public static void main(String[] args){
Circle c1 = new Circle();
double area = 3.14 * c1.radius * c1.radius;//对象名.属性名
}
}
4、属性的特点
(1)属性有默认值
基本数据类型:
byte,short,int,long:0
float,double:0.0
char:\u0000
boolean:false
引用数据类型:
null
(2)每一个对象的属性是独立,互不干扰
5、对象属性的内存图
class Student{
String name;
char gender = '男';//显式赋值
}
class TestStudent{
public static void main(String[] args){
Student s1 = new Student();
System.out.println("姓名:" + s1.name);//null
System.out.println("性别:" + s1.gender);//男
s1.name = "小薇";
s1.gender = '女';
System.out.println("姓名:" + s1.name);//小薇
System.out.println("性别:" + s1.gender);//女
Student s2 = new Student();
System.out.println("姓名:" + s2.name);//null
System.out.println("性别:" + s2.gender);//男
}
}
5.4 类的成员之二:方法
5.4.1 方法的概念
方法(method):代表一个独立的可复用的功能
目的/好处:
(1)复用
(2)简化代码
5.4.2 方法的语法
1、方法的声明格式:
【修饰符】 class 类名{
【修饰符】 返回值类型 方法名(【形参列表】){
方法体:实现功能的代码
}
}
说明:
(1)【修饰符】:待讲
(2)返回值类型:
①void:表示无返回值
②非void:所有的Java数据类型都可以
(3)方法名:能很好的体现方法的功能
命名的规范:①见名知意②从第二个单词开始首字母大写
(4)【形参列表】:
在完成这个方法的功能时,需要一些数据,这些数据要由“调用者”来决定,那我们就可以设计形参。
语法格式:
():无参,空参
(数据类型 形参名):一个形参
(数据类型1 形参名1, ......, 数据类型n 形参名n):n个形参
(5)方法体:实现方法的功能,最好一个方法就完成一个独立的功能。
2、方法的调用格式:
//本类同级别方法调用:直接调用
【变量 = 】 方法名(【实参列表】);
//在其他类的方法中调用
【变量 = 】 对象名.方法名(【实参列表】);
(1)是否传实参
看被调用的方法是否有形参
(2)是否接收返回值
看被调用的方法是否是void,如果是void,就不需要也不能接收,如果不是void,就可以接收。
3、方法的声明与调用的代码示例
(1)无参无返回值方法
//本类
class Circle{
double radius;
void printInfo(){
System.out.println("半径:" + radius);
}
void test(){
printInfo();//本类中调用无参无返回值方法
}
}
//其他类
class Circle{
double radius;
void printInfo(){
System.out.println("半径:" + radius);
}
}
class TestCircle{
public static void main(String[] args){
Circle c1 = new Circle();
c1.printInfo(); //其他类中调用无参无返回值方法
}
}
(2)无参有返回值方法
//本类
class Circle{
double radius;
double getArea(){
return 3.14 * radius * radius();
}
void printInfo(){
// System.out.println("半径:" + radius + ",面积:" + getArea());//本类中调用无参有返回值
double area = getArea();//本类中调用无参有返回值
System.out.println("半径:" + radius + ",面积:" + area);
}
}
//其他类
class Circle{
double radius;
double getArea(){
return 3.14 * radius * radius();
}
}
class TestCircle{
public static void main(String[] args){
Circle c1 = new Circle();
double area = c1.getArea();
System.out.println("面积:" + area);
//或
System.out.println("面积:" + c1.getArea());
}
}
(3)有参无返回值方法
//本类
class GraphicTools{
void printRectange(int line, int column, char sign){
for(int i=1; i<=line; i++){
for(int j=1; j<=column; j++){
Sytem.out.print(sign);
}
System.out.println();
}
}
void test(){
printRectange(5,10,'%');//本类中调用有参无返回值方法
}
}
//其他类
class GraphicTools{
void printRectange(int line, int column, char sign){
for(int i=1; i<=line; i++){
for(int j=1; j<=column; j++){
Sytem.out.print(sign);
}
System.out.println();
}
}
}
class Test{
public static void main(String[] args){
GraphicTools tools = new GraphicTools();
tools.printRectange(5,10,'%');
}
}
(4)有参有返回值方法
//本类
class MyMath{
int sum(int a,int b){
return a+b;
}
void print(){
int x = 4;
int y = 7;
System.out.println(x + "+" + y + "=" + sum(x,y);//本类中调用有参有返回值的方法
}
}
//其他类
class MyMath{
int sum(int a,int b){
return a+b;
}
}
class Test{
public static void main(String[] args){
MyMath my = new MyMath();
int x = 4;
int y = 7;
System.out.println(x + "+" + y + "=" + my.sum(x,y));
}
}
4、方法声明与调用的原则
(1)方法必须先声明后调用
如果调用方法时,如果方法名写错或调用一个不存在的方法,编译会报错
(2)方法声明的位置必须在类中方法外
正确示例:
类{
方法1(){
}
方法2(){
}
}
错误示例:
类{
方法1(){
方法2(){ //错误
}
}
}
(3)方法的调用的位置有要求
正确示例:
类{
方法1(){
调用方法
}
}
错误示例:
类{
方法1(){
}
调用方法 //错误位置
}
(4)方法的调用格式要与方法的声明格式对应
①是否要加“对象.”:看是否在本类中,还是其他类中
②是否要接收返回值:看被调用方法是否是void
③是否要传实参:看被调用方法是有形参列表
5.4.3 方法的重载Overload
概念:在同一个类中,出现了两个或多个的方法,它们的方法名称相同,形参列表不同,这样的形式称为方法的重载。和返回值类型无关。
示例代码:
//求两个整数的最大值 public int max(int a,int b){ return a>b?a:b; } //求三个整数的最大值 public int max(int a, int b, int c){ return max(max(a,b),c); } //求两个小数的最大值 public double max(double a, double b){ return a>b?a:b; }
5.4.4 方法的参数传递机制
Java中方法的参数传递机制:值传递
(1)形参是基本数据类型时,实参给形参传递数据值,是copy的形式,形参对值的修改不影响实参。 (2)形参是引用数据类型时,实参给形参传递地址值,形参对对象的属性的修改,会影响实参对象的属性值,因为此时形参和实参就是指向同一个对象。 示例代码:
class Test{
public static void swap(int a, int b){
int temp = a;
a = b;
b = temp;
}
public static void main(String[] args){
int x = 1;
int y = 2;
swap(x,y);//调用完之后,x与y的值不变
}
}
示例代码:
class Test{
public static void change(MyData my){
my.num *= 2;
}
public static void main(String[] args){
MyData m = new MyData();
m.num = 1;
change(m);//调用完之后,m对象的num属性值就变为2
}
}
class MyData{
int num;
}
陷阱1:
/*
陷阱1:在方法中,形参 = 新new对象,那么就和实参无关了
*/
class Test{
public static void change(MyData my){
my = new MyData();//形参指向了新对象
my.num *= 2;
}
public static void main(String[] args){
MyData m = new MyData();
m.num = 1;
change(m);//调用完之后,m对象的num属性值仍然为1
}
}
class MyData{
int num;
}
陷阱2:见字符串和包装类部分
5.4.5 可变参数的练习
public class srudy { public static void main(String[] arge) { MyMath my =new MyMath(); System.out.println("拼接是"+my.con("我是","你","爸爸")); System.out.println("5的阶乘是"+ my.mutiply(1,2,3,4,5)); } } class MyMath{ String con(String...args) { String str =""; for(int i=0;i<args.length;i++) { str+=args[i]; } return str; } long mutiply(int a,int...num) { long result=a; for(int i=0;i<num.length;i++) { result*=num[i]; } return result; } }
5.4.6 成员变量与局部变量
1、成员变量:
2、局部变量:
(1)初始化不同
(2)生命周期不同
(3)位置不同
①成员变量在堆中 ②局部变量在栈中
(4)声明的位置不同
①成员变量在类的方法之外 ②局部变量在类的方法之内
5.3 对象数组
一维数组:
1、元素是基本数据类型
2、元素是引用数据类型,也称为对象数组,即数组的元素是对象
注意:对象数组,首先要创建数组对象本身,即确定数组的长度,然后再创建每一个元素对象,如果不创建,数组的元素的默认值就是null,所以很容易出现空指针异常NullPointerException。
示例代码:
class MyDate{ int year; int month; int day; } class Test{ public static void main(String[] args){ MyDate[] arr = new MyDate[3];//创建数组对象本身,指定数组的长度 for(int i=0; i<arr.length; i++){ arr[i] = new MyDate();//每一个元素要创建对象 arr[i].year = 1990 + i; arr[i].month = 1 + i; arr[i].day = 1 + i; } } } public class srudy { public static void main(String[] arge) { circle[] arr =new circle[5]; for(int i=0;i<arr.length;i++) { arr[i]=new circle(); arr[i].R=i+1; arr[i].py(); } } } class circle{ double R; double getArea() { return 3.14*R*R; } void py() { System.out.println("半径是:"+ R +" 面积:"+getArea()); } }
练习
package study; public class srudy { public static void main(String[] arge) { java.util.Scanner input=new java.util.Scanner(System.in); Student[] arr=new Student[3]; for(int i=0;i<arr.length;i++) { System.out.print("请输入"+(i+1)+"成员的信息"); arr[i]=new Student(); System.out.print("姓名:"); arr[i].name=input.next(); System.out.print("成绩:"); arr[i].score=input.nextInt(); } for(int i=0;i<arr.length;i++) { arr[i].printInfo(); } System.out.println("----------------------------"); for(int i=0;i<arr.length;i++) { //第二种方式 System.out.println(arr[i].pr()); } } } class Student{ String name; int score; void printInfo(){ System.out.println("姓名"+name+" 成绩:"+score); } String pr(){ return "姓名"+name+" 成绩:"+score; } }