4.1面向过程与面向对象
类(Class)和对象(Object)是面向对象的核心概念。
类是对一类事物的描述,是抽象的、概念上的定义
对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。
“万事万物皆对象”
Java类及类的成员
现实世界的生物体,大到鲸鱼,小到蚂蚁,都是由最基本的细胞构成的。同理,Java代码世界是由诸多个不同功能的类构成的。
现实生物世界中的细胞又是由什么构成的呢?细胞核、细胞质、… 那么,Java中用类class来描述事物也是如此。常见的类的成员有:
属 性:对应类中的成员变量
行 为:对应类中的成员方法
4.3对象的创建和使用
java类的实例化,即创建类的对象
public class Animal {
public int legs;
public void eat(){
System.out.println(“Eating.”);
}
public viod move(){
System.out.println(“Move.”);
}}
public class Zoo{
public static void main(String args[]){
//创建对象
Animal xb=new Animal();
xb.legs=4;//访问属性
System.out.println(xb.legs);
xb.eat();//访问方法
xb.move();//访问方法
} }
static方法可以不需要创建对象直接使用,而非静态的属性需要对象创建才可以使用,所有静态方法中不可以有非静态的属性和方法
堆:全局变量;new出来的对象(对象实例)
寨:局部变量,对象的引用
方法区:静态变量,常量
我们也可以不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象。如:new Person().shout();
使用情况
如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
我们经常将匿名对象作为实参传递给一个方法调用。4.4类的成员之一:属性
权限修饰符 数据类型 属性名 = 初始化;
说明1:修饰符:private、缺省、protected、public
其他修饰符:static、final
2.数据类型:任何数据类型
3.属性名:标识符
变量的分类:成员变量局部变量
在方法体外,类体内声明的变量称为成员变量
在方法体内部声明的变量称为局部变量成员变量:类变量(static)实例变量
局部变量:形参,方法局部变量,代码块局部变量
成员变量(属性)和局部变量的区别?
class Person{//人类
//1.属性
String name;//姓名
int age = 1;//年龄
boolean isMale;//是否是男性
public void show(String nation){
//nation:局部变量
String color;//color:局部变量
color = "yellow";
} }
//测试类
class PersonTest{
public static void main(String[] args){
Person p = new Person();
p.show(“USA”);
} }
对象属性的默认初始化赋值
当一个对象被创建时,会对其中各种类型的成员变量自动进行初始化赋值。除了基本数据类型之外的变量类型都是引用类型,如上面的Person及前面讲过的数组。
4.5类的成员之二:方法
什么是方法(method、函数):
方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中
也称为函数或过程。
将功能封装为方法的目的是,可以实现代码重用,简化代码
Java里的方法不能独立存在,所有的方法必须定义在类里。
public class Person{
private int age;
public int getAge() { //声明方法getAge()
return age;
}
public void setAge(int i) { //声明方法setAge
age = i; //将参数i的值赋给类的成员变量age
} }
方法的声明格式:
修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ….){
方法体程序代码
return 返回值; }
注 意:
1.方法被调用一次,就会执行一次
2.没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可以不必使用return语句。如果使用,仅用来结束方法。
3.定义方法时,方法的结果应该返回给调用者,交由调用者处理。
4.方法中只能调用方法或属性,不可以在方法内部定义方法。
返回值为void时使用return会结束方法
练习3 4. 对象数组题目:
定义类Student,包含三个属性:学号number(int),年级state(int),成绩
score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
提示:
1) 生成随机数:Math.random(),返回值类型double;
2) 四舍五入取整:Math.round(double d),返回值类型long。
5.声明一个日期类型MyDate:有属性:年year,月month,日day。创建2个日期
对象,分别赋值为:你的出生日期,你对象的出生日期,并显示信息。
4.6方法:
4.6.1方法的重载:
重载是编译时就是分别开
判 断:
与void show(int a,char b,double c){}构成重载的有:
a) void show(int x,char y,double z){} // no:一模一样
b) int show(int a,double c,char b){} // yes
c) void show(int a,double c,char b){} // yes
d) boolean show(int c,char b){} // yes
e) void show(double c){} // yes
f) double show(int x,char y,double z){} // no:只有返回值不一样不是重载
g) void shows(){double c} // no:方法名都不一样
练习4
2.编写程序,定义三个重载方法并调用。方法名为mOL。 三个方法分别接收一个int参数、两个int参数、一个字符串参数。分别
执行平方运算并输出结果,相乘并输出结果,输出字符串信息。
在主类的main ()方法中分别用参数区别调用三个方法。
3.定义三个重载方法max(),第一个方法求两个int值中的最大值,第二个方
法求两个double值中的最大值,第三个方法求三个double值中的最大值,
并分别调用三个方法。
基本数据都是值传递,就是出来方法以后他是不会保留改变的
引用数据类型时地址传递就是从方法中出来以后值会发生变化
public class TransferTest1 {
public void swap(int a, int b) {
int tmp = a; a = b; b = tmp;
System.out.println("swap方法里,a的值是" + a + ";b的值是" + b);
}
public static void main(String[] args) {
TransferTest1 test = new TransferTest1();
int a = 5;
int b = 10;
test.swap(a, b);
System.out.println("交换结束后,变量a的值是" + a + ";变量b的值是" + b);
输出的结果为: swap方法里,a的值是10;b的值是5
交换结束后,变量a的值是5;变量b的值是10
} }
class DataSwap {
public int a;
public int b; }
public class TransferTest2 {
public static void swap(DataSwap ds) {
int temp = ds.a;
ds.a = ds.b;
ds.b = temp;
System.out.println("swap方法里,a Field的值是" + ds.a + ";b Field的值是" + ds.b);
}
public static void main(String[] args) {
DataSwap ds = new DataSwap();
ds.a = 5;
ds.b = 10;
swap(ds);
System.out.println("交换结束后,a Field的值是" + ds.a + ";b Field的值是" + ds.b);
//地址传递,在方法外会发生改变
} }
public class TransferTest3 {
public static void main(String args[]) {
TransferTest3 test = new TransferTest3();
test.first();
}
public void first() {
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
System.out.println(v.i);
}
public void second(Value v, int i) {
i = 0;
v.i = 20;
Value val = new Value();
v = val;
System.out.println(v.i + " " + i);
} }
class Value {
int i = 15;
}
1.貌似是考查方法的参数传递method方法不会改变a,b的值
public class Test {
public static void main(String[] args) {
int a=10;
int b=10;
method(a,b);//需要在method方法被调用之后,仅打印出a=100,b=200,
//请写出method方法的代码
System.out.println("a="+a);
System.out.println("b="+b);
}
//代码编写处
}
方法一:通过使用System.exit()方法退出程序
static void method(Integer a,Integer b){
System.out.println("a="+a*10);
System.out.println("b="+b*20);
System.exit(0); //退出程序
}
方法二:改变打印流
static void method(Integer a,Integer b){
PrintStream printStream = new PrintStream(System.out){
@Override
public void println(String x) {
if("a=10".equals(x)){
x="a=100";
}else if("b=10".equals(x)){
x="b=200";
}
super.println(x);
}
};
System.setOut(printStream);
}
public class ArrayPrintTest {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3};
System.out.println(arr);//地址值
char[] arr1 = new char[]{'a','b','c'};
System.out.println(arr1); //abc
}
}
int[] arr = new int[10];
System.out.println(arr);//地址值?是
char[] arr1 = new char[10];
System.out.println(arr1); //地址值?不是,输出默认值
递归:
4.7封装与隐藏
class Animal {
public int legs;
public void eat(){
System.out.println("Eating");
}
public void move(){
System.out.println("Moving.");
} }
public class Zoo {
public static void main(String args[]) {
Animal xb = new Animal();
xb.legs = 4;
System.out.println(xb.legs);
xb.eat();
xb.move();
} }
//应该将legs属性保护起来,
防止乱用。
保护的方式:信息隐藏
Java中通过将数据声明为私有的(private),再提供公共的(public)
方法:getXxx()和setXxx()实现对该属性的操作,以实现下述目的:
隐藏一个类中不需要对外提供的实现细节;
使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,
限制对属性的不合理操作;
便于修改,增强代码的可维护性;
class Animal {
private int legs;// 将属性legs定义为private,只能被Animal类内部访问
public void setLegs(int i) { // 在这里定义方法 eat() 和 move()
if (i != 0 && i != 2 && i != 4) {
System.out.println("Wrong number of legs!");
return; }
legs = i; }
public int getLegs() {
return legs; } }
public class Zoo {
public static void main(String args[]) {
Animal xb = new Animal();
xb.setLegs(4); // xb.setLegs(-1000);
//xb.legs = -1000; // 非法
System.out.println(xb.getLegs());
} }
4.8构造器
public class Person {
private String name;
private int age;
private Date birthDate;
public Person(String n, int a, Date d) {
name = n;
age = a;
birthDate = d; }
public Person(String n, int a) {
name = n;
age = a; }
public Person(String n, Date d) {
name = n;
birthDate = d; }
public Person(String n) {
name = n;
age = 30;
} }
总结:属性赋值过程
1.默认赋值
2.显示赋值
3.构造器赋值
4.对象或方法.属性赋值
//javabean实例
public class JavaBean {
private String name; // 属性一般定义为private
private int age;
public JavaBean() {
}
public int getAge() {
return age; }
public void setAge(int a) {
age = a; }
public String getName() {
return name; }
public void setName(String n) {
name = n; } }
4.9this的使用
使用this,调用属性、方法
class Person{ // 定义Person类
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ; }
public void getInfo(){
System.out.println("姓名:" + name) ;
this.speak();
}
public void speak(){
System.out.println(“年龄:” + this.age);
} }
class Person{ // 定义Person类
String name;
Person(String name){
this.name = name;}
public void getInfo(){
System.out.println("Person类 --> " + this.name) ; }
public boolean compare(Person p){
return this.name==p.name;
} }
public class PersonTest{
public static void main(String args[]){
Person per1 = new Person("张三") ;
Person per2 = new Person("李四") ;
per1.getInfo() ; // 当前调用getInfo()方法的对象是per1
per2.getInfo() ; // 当前调用getInfo()方法的对象是per2
boolean b = per1.compare(per2);
} }
使用this调用本类的构造器
使用this调用本类的构造器
class Person{ // 定义Person类
private String name ;
private int age ;
public Person(){ // 无参构造器
System.out.println("新对象实例化") ;
}
public Person(String name){
this(); // 调用本类中的无参构造器
this.name = name ;
}
public Person(String name,int age){
this(name) ; // 调用有一个参数的构造器
this.age = age;
}
public String getInfo(){
return "姓名:" + name + ",年龄:" + age ;
}
}
注意:
可以在类的构造器中使用"this(形参列表)"的方式,调用本类中重载的其
他的构造器!
明确:构造器中不能通过"this(形参列表)"的方式调用自身构造器
如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了
"this(形参列表)"
"this(形参列表)"必须声明在类的构造器的首行!
在类的一个构造器中,最多只能声明一个"this(形参列表)"
4.10package,import的使用