学习面向对象(OOP)编程的三条主线
1.java类及类的构成成分:属性 方法 构造器 代码块 内部类
2.面向对象的三大特征(封装性 Encapsulation,继承性 Inheritance,多态性 Polymorphism,(抽象性))
3.其他关键字
OOP:Object Oriented Programming
面向过程:procedure oriented programming
理解一:人开门
面向过程:人 打开 门
面向对象:
人{
打开(门){
门.开开();
}
}
门{
开开(){
}
}
理解二:人把大象装进冰箱
面向过程:1)打开冰箱 2)把大象放进去 3)关闭冰箱
面向对象:
人{
打开(冰箱){冰箱.开开()}
操作(大象){大象.进入(冰箱)}
关闭(冰箱){冰箱.合上()}
}
大象{
进入(冰箱){}
}
冰箱{
开开(){}
合上(){}
}
类与类之间的关系:
关联关系,继承关系,聚合关系
Field=属性=成员变量,Method=(成员)方法=函数
一、面向对象思想的落地法则一:
1.设计类,并设计类的成员(成员变量&成员方法)
2.通过类,未创建类的对象(也称作类的实例化)
3.通过“对象.属性”或“对象.方法”来调用,完成相应的功能
二、创建的多个对象,彼此各自拥有一套类的属性,当对其中一个对象的属性进行修改时,不会影响到其他对象的属性
//a3不意味着重新创建的一个对象,而是a1与a3公用一个对象实体
Animal a3=a1;
System.out.print("name"+a3.name+"age"+a3.age);
a3.name="维尼熊";
System.out.print("a1.name"+a1.name+"age"+a1.age);
三、类的属性(成员变量,Field)
成员变量vs局部变量
相同点:1.遵循变量的声明格式。数据类型 变量名=初始化值
2.都有作用域
不同点:1.声明的位置不同:成员变量:声明在类内,方法外
局部变量:声明在方法内,方法的形参部分,代码块内
2.成员变量的修饰符有四个:public private protected 缺省
局部变量没有修饰符,与所在的方法修饰符相同
3.初始化值:一定会有初始化值
成员变量:如果在声明的时候,不显式的赋值,那么不同数据类型会有不同的初始化值
byte short int long==>0
float double ==>0.0
char==>空格
boolean==>false
引用类型变量==>null
局部变量:一定要显式的赋值。(局部变量没有默认初始化值)
4.二者在内存中存放的位置不同:成员变量存在于堆空间中,局部变量:栈空间中
总结:关于变量的分类:1)按照数据类型的不同:基本数据类型(8种)&引用数据类型
2)按照声明的位置不同,成员变量&局部变量
四、类的方法(函数,Method):提供某种功能的实现
public int getAge(){
return age;
//其后不可以声明语句
//System.out.println("hello");
类的访问机制:
在一个类中的访问机制:类中的方法可以直接访问类中的成员变量。(例外:static方法访问非static,编译不通过。)
在不同类中的访问机制:先要访问类的对象,再用对象访问类中定义的成员。
要求 :1.同一个类中 2)方法名必须相同 3)方法的参数列表不同 (1.参数的个数不同 2.参数的类型不同)
补充:方法的重载与方法的返回值类型没有关系!
class Overload{
//以下四个方法之间都构成重载
public int getSum(int i,int j){
return i+j;
}
public int getSum(int i,int j,int k){
return i+j+k;
}
public double getSum(double d1,double d2){
return d1+d2;
}
public void getSum(double d1,double d2,double d3){
System.out.println(d1+d2+d3);
}
//以下两个方法也构成重载
public void method1(int i,String str){
}
public void method1(String str1,int j){
}
}
类的初始化的内存解析
1)内存划分的结构:
栈(stack):局部变量、对象的引用名、数组的引用名
堆(heap):new 出来的“东西”(如:对象的实体,数组的实体),含成员变量 方法区:含字符串常量
静态域:声明为static的变量
创建的类的对象是 匿名的
1)当我们只需要调用一次类的对象的时候,就可以考虑使用匿名的方式创建类的对象。
2)特点,创建的匿名类的对象只能够调用一次!
class Circle{
double radius;
public double findArea(){
return Math.PI*radius;
}
public void setRadius(double r){
radius=r;
}
public double getRadius(){
return radius;
}
public void show(){
System.out.println("我是一个圆");
}
}
public class PassObject{
public void printAreas(Circle c,int time){
int temp=0;
System.out.print("Radius"+"\t\t"+"Area");
for(int i=1;i<=time;i++,temp=i){
c.setRadius(i);
System.out.print(c.getRadius()+"\t\t"+c.findArea());
}
c.setRadius(temp);
}
public static void main (String[] args){
PassObject p=new PassObject();
Circle c=new Circle();//此时c为半径0
p.printArea(c,5);
System.out.println("now radius is "+c.getRadius());
System.out.println();
p.printArea(new Circle(),6);
System.out.print("Radius"+"\t\t"+"Area");
new Circle().show();
new Circle().setRadius(2.3);//只能调用一次,堆空间没有名指向它,用完一次后回收
}
1.格式:对于方法的形参:数据类型...形参名
2.可变个数的形参的方法与同名的方法之间构成重载
3.可变个数的形参在调用时,个数从0开始,到无穷多个都可以。
4.使用可变多个形参的方法与方法的形参使用数组是一致的
5.若方法中存在可变个数的形参,那么一定要声明在方法形参的最后
6.在一个方法中,最多声明一个可变个数的形参
public class TestArgs{
public static void main(String[] args){
TestArgs t=new TestArgs();
t.sayHello();
//t.sayHello(new String[]{"hello China","hello Beijing"})
t.sayHello("hello China","hello Beijing")
}
//如下四个方法构成重载
//在类中一旦定义了重载的可变个数的形参的方法以后,如下的两个方法可以省略(它们处理的方法一致)
//public void sayHello(){
// System.out.println("hello world");
//}
//public void sayHello(String str1){
//System.out.println("hello world"+str1);
//}
//可变个数的形参的方法
public void sayHello(String ... args){//可以跟第一,二个函数构成重载,若把第四个函数的方法名改为sayHello,则程序报错,它与第四个函数不构成重载
for(int i=0;i
1.形参:方法声明时,方法小括号的参数
实参:调用方法时,实际传入的参数的值
2.规则:java中的参数传递机制:值传递机制
1)形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量
2)形参是引用数据类型的:将实参的引用类型变量的值(对应的堆空间的对象实体的首地址值)传递给形参的引用类型变量
1)形参是基本数据类型的
public class TestArgsTransfer{
public static void main(String[] args){
TestArgsTransfer tt=new TestArgsTransfer();
int i=10;
int j=5;
System.out.println("i"+i+"j"+j);
//交换变量i与j的值
//int temp=i;
//i=j;
//j=temp;
tt.swap(i,j);//将i的值传递给m,j的值传递给n
System.out.println("i:"+i+" j:"+j);//i:10 j:5
}
//定义一个方法,交换两个变量的值
public void swap(int m,int n){
int temp=m;
m=n;
n=temp;
System.out.println("m:"+n+" m:"+n);//m:5 n:10
}
2)形参是引用数据类型的
public class TestArgsTransfer1{
public static void main(String[] args){
TestArgsTransfer1 tt=new TestArgsTransfer1();
DataSwap ds= new DataSwap();
System.out.println("ds.i: "+ds.i+" ds.j"+ds.j);
tt.swap(ds);
System.out.println(ds);
System.out.println("ds.i:"+ds.i+" ds.j:"+ds.j);
}
//交换元素的值
public void swap(DataSwap d){
int temp=d.i;
ds.i=d.j;
d.j=temp;
System.out.println(d);//打印引用变量d的值
}
}
class DataSwap{
int i=10;
int j=5;
}
【方法的值传递机制练习】
面向对象的特征一:封装与隐藏
问题:当创建了类的对象以后,如果直接通过“对象.属性”的方式堆相应的对象赋值的话,可能会出现不满足实际情况的意外,我们考虑不让对象来直接作用属性,而是通过“对象.方法”的形式,来控制对象属性的访问。实际情况 中,对属性的要求就可以通过方法来实现。
解决的方法:(封装性的思想)①将类的属性私有化 ②提供公共的方法(setter&getter)来实现调用。
public class TestAnimal{
public static void main(String[] args){
Animal a1=new Animal();
//a1.name="花花";
//a1.legs=-4;
a1.setLegs(4);
a1.setName("小花");
a1.info();;
a1.eat();
}
class Animal{
private String name;//动物的名字
private int legs;//腿的个数
public void eat(){
System.out.println("动物进食");
}
public void sleep(){
System.out.println("动物睡觉");
}
public void info(){
System.out.println("name:"+name+" legs:"+legs);
}
//设置类的属性(有形参无返回值)
public void setLegs(int l){
if(l>0&&l%2==0){
legs=l;
}else{
System.out.println("您输入的数据有误!");
}
}
//获取类的属性(又返回值无形参)
public int getLegs(){
return legs;
}
public void setName(String n){
//...
name=n;
}
public String getName(){
return name;
}
}
public private 缺省(deaufult,可以不写) protected
可以用来修饰属性、方法
权限从小到大排列: