面向对象
面向过程,全部细节要自己一 一去实现
面向过程,当需要实现一个功能的时候,不关心具体的步骤,直接调用对象的方法
面向对象三大特性
- 继承
- 封装
- 多态
例:要求打印:[10,20,30,40,50]
面向过程的写法,每一个细节要亲力亲为
public class a{
public staic int sumTwo(int a,int b)
{
return a+b;
}
public static void main(String[] args)
{
int[] array={10,20,30,40,50};
System.out.print("[");
for(int i=0;i<array.length-1;i++)
{
if(i=array.length-1){
System.out.pritnln(array[i]+"]")
}
else
{
System.out.print(array[i]+",");
}
}
}
}
改进使用面向对象
类似于生活中的洗衣服,
面向过程:把衣服脱下来->找一个盆->放洗粉->加水->浸泡十分钟->揉一揉->清洗衣服->拧干->晾衣服
面向对象:把衣服脱下来->打开全自动洗衣机->扔衣服->按钮->晾衣服
//找到JDK提供好的Array类
//其中有一个toString方法,直接能把数组变成字符串
import java.util.Arrays;
public class a{
public static void main(String[] args)
{
int[] array={10,20,30,40,50};
System.out.println(Arrays.toString(array));
}
}
类
类是对象的模板,对象是类的实体
实例化,就可以创建对象
- 属性
- 行为
例如:小猫
属性:名字,体重,年龄,颜色
行为:走、跑、叫
定义类
定义一个类,用来模拟学生
属性(是什么):姓名,年龄
行为(能做什么):吃饭,睡觉,学习
在JAVA类里的术语,
成员变量(属性):
String name;//姓名
int age;//年龄
,成员方法(行为)不使用static关键字:
public void eat(){}//吃饭
public void sleep(){}//睡觉
public void study(){}//学习
public class student
{
//**成员变量**
String name;//姓名
int age;//年龄
//成员方法
public void eat(){System.out.println("吃饭")};//吃饭
public void sleep(){System.out.println("睡觉"};//睡觉
public void study(){System.out.println("学习")};//学习
}
类的使用
不能直接使用类里的内容,需要根据类创建一个对象才能使用
创建对象的过程
-
导包,也就是指出需要使用的类,在什么位置
import 包名称.类名称
但当类在同一个包里进行创建,可以省略导包语句 -
创建
类名称 对象名=new 类名称();
Student stu =new Student(); -
使用
使用成员变量,对象名.成员变量
使用成员方法,对象名.成员方法
public class a{
public static void main(String[] args)
{
//创建对象
Student stu =new Student();
//使用对象
//无赋值,默认赋值为null
System.out.println(stu.name);
//无赋值,默认赋值为0
System.out.println(stu.age);
//赋值
stu.name="a";
stu.age=20;
//输出a 20
System.out.println(stu.name);
System.out.println(stu.age);
//使用对象的方法
stu.eat();
stu.sleep();
stu.study();
}
}
手机类
属性:品牌,性格,颜色
行为:打电话,发短信
对应的类当中
成员变量
String brand;
double price;
String color;
成员方法
public void call(String who){}
public void sendMessage(){}
public class Phone{
//成员变量
String brand;
double price;
String color;
//成员方法
public void call(String who)
{
System.out.println("给"+who+"打电话");
}
public void sendMessage(){"群发短信"}
}
public class a{
public static void main(String[] args)
{
//创建对象
Phone one=new Phone();
//为对象属性赋值
one.brand="苹果";
one.price=8388.0;
one.color="黑色";
//调用成员方法
one.call("我");
one.sendMessage();
}
}
首先在系统里面数据的存放,方法区里面存放了两个类
- Phone
- Demo01PhoneOne
然后在栈里面创建对象,Phone one,new Phone(),生成对象的地址0x666,成员变量就保存在这个堆里,而在堆里保存的是成员方法的地址
当修改成员变量的时候,修改0x666里的变量值,当调用成员方法时,是把方法进行压栈,利用0x666成员方法的地址,调用方法区里的成员方法
当有两个对象
public class a{
public static void main(String[] args)
{
//创建对象1
Phone one=new Phone();
//为对象属性赋值
one.brand="苹果";
one.price=8388.0;
one.color="黑色";
//调用成员方法
one.call("我");
one.sendMessage();
//创建对象2
Phone two=new Phone();
//为对象属性赋值
two.brand="三星";
two.price=5999 .0;
two.color="蓝色";
//调用成员方法
two.call("他");
two.sendMessage();
}
}
这里有一点值得注意的是,两个对象的地址不同,但他们调用的成员方法的地址相同
两个对象联系在一起,Phone two=one;
这里控制的是同一个对象 ,地址都是0x666
public class a{
public static void main(String[] args)
{
//创建对象1
Phone one=new Phone();
//为对象属性赋值
one.brand="苹果";
one.price=8388.0;
one.color="黑色";
//调用成员方法
one.call("我");
one.sendMessage();
//两个对象联系在一起
Phone two=one;
//为对象属性赋值
two.brand="三星";
two.price=5999 .0;
two.color="蓝色";
//调用成员方法
two.call("他");
two.sendMessage();
}
}
使用对象类型作为,函数的参数值,Phone param
传递对象地址值
public class a{
public static void method(Phone param)
{
System.out.println(param.brand);
System.out.println(param.price);
System.out.println(param.color);
}
public static void main(String[] args)
{
//创建对象1
Phone one=new Phone();
//为对象属性赋值
one.brand="苹果";
one.price=8388.0;
one.color="黑色";
//调用方法,传递对象的地址值
method(one);
}
}
使用对象类型作为函数的返回值
public class a{
public static void main(String[] args)
{
//创建对象,接收函数的返回值,接收地址
Phone one=getPhone();
}
public static Phone getPhone(){
Phone one=new Phone();
one.brand="苹果";
one.price=8388.0;
one.color="玫瑰金";
return one;
}
}
成员变量和局部变量
- 成员变量是直接写在类(class)里面,局部变量写在方法public static void main里面
- 成员变量像数组一样,会有默认值,局部变量,没有默认值,如要想要使用,必须手动赋值。
- 成员变量,只有方法当中才可以使用,出了方法就不能使用,成员变量整个类都可以使用
- 局部变量位于栈内存,成员变量位于堆内存
- 生命周期不一样 ,局部变量随着方法进栈,随着方法出栈而消失,成员变量,随着对象创建而诞生,随着对象被垃圾回收而消失
public class a{
##成员变量,直接在类里面,方法外面
String name;
##局部变量,在方法里面
##由于参数值不是直接在类里面,所以它属于局部变量,局部变量需要赋初值,在调用这个方法的时候就会赋初值
public void methodA(int param){
int num=20;
System.out.println(num);
System.out.println(name);
}
public void methodB{
##错误,num是methodA里的局部变量,不能调用
System.out.println(num);
System.out.println(name);
##错误,局部变量需要赋初值
int age;
System.out.println(age);
}
}
封装性
- 方法就是一种封装
- 关键字private也是一种封装
- 将一些细节信息封装隐藏起来,对于外界不可见
取其中的最大值
public class a{
public static void main(String[] args)
{
int[] array={5,15,25,20,100};
int max=getMax(array);
}
}
//接收数组,求最大值
public static int getMax(int[] array)
{
int max=array[0];
for(int i=1;i<array.length;i++)
{
if(array[i]>max)
{
max=array[i];
}
return max;
}
}
private
使用了private关键字,本类里面还能访问,但超出本类范围就不能再访问了
要使用Getter/Setter去间接访问成员变量
命名规则必须是setxxx,getxxx,并且getter,不能有参数,返回值类型和成员变量对应,对于setter来说,不能有返回值,参数类型和成员变量对应
public class Person{
String name;//姓名
private int age;//年龄
public void show(){
System.out.println("我叫,"+name+",年龄:"+age);
}
}
public class a{
public static void main(String[] args)
{
Person person=new Person();
person.show();
person.name="a";
##错误,不在Person类范围里面
person.age=18;
person.show();
}
}
改进方法
public class Person{
String name;//姓名
private int age;//年龄
//这个成员方法,专门用于age设置数据
public void setAge(int num)
{
if(num<100&&num>=9)
{
age=num;
}
else
{
System.out.println("数据不合理");
}
age=num;
}
//这个成员方法,用来返回age的数值
public int getAge()
{
return age;
}
public void show(){
System.out.println("我叫,"+name+",年龄:"+age);
}
}
public class a{
public static void main(String[] args)
{
Person person=new Person();
person.show();
person.name="a";
##会因为数据不合理,显示错误信息
person.setAge(-20);
person.setAge(20);
person.show();
}
}
练习使用private关键字定义学生类
public class Student{
private String name;
private int age;
##boolean类型get的特例
private boolean male;
//对male的get
public void setMale(boolean b)
{
male=b;
}
##这里用的不是get,**而是isxxx**
public boolean isMale(boolean b)
{
return male;
}
//对name的set和get
public void setName(String str)
{
name=str;
}
public String getName()
{
return name;
}
//对age的set和get
public void setName(int num)
{
age=num;
}
public String getName()
{
return age;
}
}
调用类
public class a{
public static void main(String[] args)
{
Student stu=new Student();
stu.setName("wo");
stu.setAge(20);
stu.setMale(true);
System.out.println("姓名"+stu.getName()+"年龄"+stu.getAge()+"是不是男的"+stu.isMale());
}
}
this关键字
通过谁调用方法,谁就是this
public class Person{
String name;//自己的名字
public void sayHello(String name)
{
//前面的name是对方名字,后面的name是自己的名字
##重名的时候使用就近原则,会优先使用参数里的
System.out.println(name+",你好。我是"+name);
}
}
调用类
public class a{
public static void main(String[] args)
{
Person person=new Person();
}
}
改进
在重名的情况下,需要访问本地的成员变量,需要使用格式:this.变量名
public class Person{
String name;//自己的名字
public void sayHello(String name)
{
//前面的name是对方名字,后面的name是自己的名字
##重名的时候使用就近原则,会优先使用参数里的
System.out.println(name+",你好。我是"+this.name);
}
}
public class a{
Person person=new Person();
Person.name="wo";
#通过Person调用方法,Person就是this,所以this.name=Person.name="wo"
Person.sayHello("ta")
}
}
#输出
ta,你好。我是wo
构造方法
专门用来创建对象的方法,当通过关键字new来创建对象时,就是在调用构造方法
public 类名称(参数类型 参数名称)
{
}
注意
- 和类名称完全一样
- 不用写返回值类型
- 如果没有编写任何构造方法,编译器会自动生成一个构造方法,没有参数
- 一旦编写了一个构造方法,那编译器将不再自动生成
- 构造方法也可以重载,参数名称相同,参数列表不同
构造方法只是对变量做初始化,如果后期需要改变还是需要调用set和get方法
public class Student{
//成员变量
private String name;
private int age;
//全参数的构造方法
public student(String name,int age){
System.out.println("全参构造方法执行");
this.name=name;
this.age=age;
}
//无参数的构造方法
//当写了一个,编译器不会自动生成无参的构造方法,想继续有无参的构造方法,要自己写
public student(){
System.out.println("无构造方法执行");
}
//getter and setter
public void setName(String name)
{
this.name=name;
}
public void getName()
{
return name;
}
}
public class a{
public static void main(String[] args)
{
#new对象就是在调用无参构造方法
Student stu=new Student();
#new对象就是在调用全参构造方法
Student stu2=new Student("a",20);
System.out.println("姓名:"+stu2.getName()+",年龄:"+stu2.getAge());
##后期改变
stu2.setAge(21);
}
}
定义一个标准类
JAVA Bean
- 所有的成员变量都要使用private关键字修饰
- 为每一个成员变量编写getter和setter方法
- 编写一个无参数的构造方法
- 编写一个全参数的构造方法
1.手动写
2.选择generate,选择Getter and setter
3.选择generate,constructor,select none
4.选择generate,constructor,选择全部成员变量