面向对象(Object Oriented)
一、面向对象杂谈
面向对象(Object Oriented),我的翻译是以物体为目标的,就是说编程的时候是建立一个物体,然后对这个物体进行操作。
Java语言是面向对象的(有95%都是面向对象的内容),C++是基于对象的
计算机语言的发展向接近人的思维方式演变
- 汇编语言 [面向机器]
- c语言 [面向过程]
- java语言 [面向对象]
- spring [面向切面]———— 把类在进行切分
二、类和对象的关系————(类class,对象object)
三、创建一个简单的类
class Cat //类名首字母要大写 { int age; String name; String color; }
四、类和对象的区别和联系
- 类是抽象的,概念的,代表一类事物——只能找到人,找不到人类
- 对象是具体的,实际的,代表一个具体的事物
- 类是对象的模板,对象是类的一个个体,实例
五、定义一个全面的类 —— 一个全面的类定义比较复杂
package 包名; class 类名 extends 父类 implements 接口名{ 成员变量; 构造方法; 成员方法; }
类——类的成员变量
成员变量是类的一个组成部分,一般是基本数据类习惯,也可是引用类型。比如我们前面定义猫类的 int age 就是实例变量,属于成员变量。
实例变量、类变量、常量都是属于成员变量的,成员变量又被称为全局变量
引用类型是什么呢?
假如说猫要有一个主人,这个主人也有年龄,身高等信息
通俗来讲就是类指向另外一个类,叫做引用,例如:
class Cat { int age; String name; String color; //其实它也是一个引用类型,Java中String本身就是一个类 Myster myMaster; //这就是一个引用类型 } class Master { int age; String name; String address; }
类与对象
一、创建对象的两种方法
- 1、先声明再创建——没人用了!
- 2、一步到位法
1、先声明再创建 对象声明:类名 对象名 对象创建:对象名 = new 类名() Cat cat1=new Cat(); 2、一步到位法 类名 对象名 = new 类名(); Cat cat1; cat1 = new Cat;
二、如何 访问/使用 对象的成员变量
对象名.变量名 cat1.age=3; cat1.name="小白"; cat1.color="黄色";
思考:
public class Demo6 { public static void main(String []args) { Person a=new Person(); a.age = 10; a.name="小明"; Person b; b = a; //问b.age是多少?? System.out.println("b.age="+b.age); Person c; c = a; c.age = 9; //问改变c.age的值,a.age和b.age的值会变吗?? System.out.println("a.age="+a.age); System.out.println("b.age="+b.age); System.out.println("c.age="+c.age); } } class Person { int age; String name; } 运行结果: D:myJavaDemo>java Demo6 b.age=10 a.age=9 b.age=9 c.age=9
原理:创建对象a的时候开辟了一块内存,之后相当于让b和c的地址也指向了那块地址,所以对c.age进行操作时,a.age和b.age的值也跟着变化了
三、对象在内存中的存在形式
我们用new这个方法创造的对象,放到了内存中
了解一下:java的垃圾回收机制,如果对象没有人指向,就认为这个对象是垃圾,在适当的时候去回收。
类的成员方法
在某些情况下我们需要定义类的成员方法。比如人类:
- 除了有一些属性外(例如:成员变量表示的年龄,姓名等)
- 我们人类还有一些行为比如:可以说话,跑步
- 通过学习我们还可以做算术题
- 这时就要用成员方法才能完成
现在我们来对Person类完善
- 添加speak 成员方法,输出——我是一个好人
- 添加jisuan 成员方法,可以计算从1+..+1000的结果
- 修改jisuan 成员方法,该方法可以接受一个数n,计算从1+..+n的结果
- 添加add 成员方法, 可以计算两个数的和
成员方法的定义
成员方法也叫成员函数
public 返回数据类型 方法名 (参数列表) { 语句; //函数(方法)主体 } /* 1. 参数列表: 表示成员函数输入 2. 数据类型(返回类型): 表示成员函数输出 3. 函数主体: 表示为了实现某一功能代码块 */
speak成员方法
1 public class Demo6 2 { 3 public static void main(String []args) 4 { 5 //使用成员方法 6 Person p1=new Person(); 7 p1.speak(); //调用speak方法 8 } 9 } 10 class Person 11 { 12 int age; 13 String name; 14 15 //定义成员方法 16 public void speak() 17 { 18 System.out.println("我是一个好人"); 19 } 20 21 }
jisuan成员方法
注:类名的首字母是大写的,方法名的首字母是小写的,常用的命名方法有
- 驼峰法(匈牙利法)——myCry
- 下划线法——my_cry
1 public class Demo6 2 { 3 public static void main(String []args) 4 { 5 //使用成员方法 6 Person p1=new Person(); 7 p1.jiSuan(); //调用jisuan方法 8 } 9 } 10 class Person 11 { 12 int age; 13 String name; 14 15 //计算方法 16 public void jiSuan() 17 { 18 int result = 0; 19 for (int i=1;i<=1000;i++) 20 { 21 result+=i; 22 } 23 //输出结果 24 System.out.println(result); 25 } 26 27 }
强换版计算成员方法
1 public class Demo6 2 { 3 public static void main(String []args) 4 { 5 //使用成员方法 6 Person p1=new Person(); 7 p1.jiSuan(); 8 p1.jiSuan(8); //调用jisuan方法 9 } 10 } 11 class Person 12 { 13 int age; 14 String name; 15 //jisuan成员方法 16 public void jiSuan() 17 { 18 int result = 0; 19 for (int i=1;i<=1000;i++) 20 { 21 result+=i; 22 } 23 //输出结果 24 System.out.println(result); 25 } 26 27 //带参数的成员方法 28 public void jiSuan(int n) 29 { 30 int result = 0; 31 for (int i=1;i<=n;i++) 32 { 33 result+=i; 34 } 35 //输出结果 36 System.out.println(result); 37 } 38 }
从中可以看出两个问题,
- 第一个是:定义两个成员方法时都使用了result这个变量,但不会引起冲突,因为作用域不同
- 第二个是:两个成员方法的名字相同都是 jiSuan ,但不会报错,因为区别是一个带参数,另一个不带
函数调用的原理图
注意:如果语句三也调用了一个函数,则它也会开辟一个新的函数栈,这也解释了为什么两个函数中都有result
add成员方法
1 public class Demo6 2 { 3 public static void main(String []args) 4 { 5 //使用成员方法 6 Person p1=new Person(); 7 p1.jiSuan(); 8 p1.jiSuan(20); 9 p1.add(20,35); 10 } 11 } 12 class Person 13 { 14 int age; 15 String name; 16 17 //jisuan成员方法 18 public void jiSuan() 19 { 20 int result = 0; 21 for (int i=1;i<=1000;i++) 22 { 23 result+=i; 24 } 25 //输出结果 26 System.out.println(result); 27 } 28 29 //带参数的成员方法 30 public void jiSuan(int n) 31 { 32 int result = 0; 33 for (int i=1;i<=n;i++) 34 { 35 result+=i; 36 } 37 //输出结果 38 System.out.println(result); 39 } 40 41 //计算两个数的和 42 public void add(int num1,int num2) 43 { 44 int result = 0; 45 result = num1+num2; 46 System.out.println(result); 47 } 48 }
把add成员方法也改名为jiSuan
1 /* 2 作者:侯召晖 3 日期:28.9.6 4 功能:找猫问题 5 */ 6 public class Demo6 7 { 8 public static void main(String []args) 9 { 10 //使用成员方法 11 Person p1=new Person(); 12 p1.jiSuan(); 13 p1.jiSuan(20); 14 p1.jiSuan(20,35); 15 } 16 } 17 class Person 18 { 19 int age; 20 String name; 21 22 //jisuan成员方法 23 public void jiSuan() 24 { 25 int result = 0; 26 for (int i=1;i<=1000;i++) 27 { 28 result+=i; 29 } 30 //输出结果 31 System.out.println(result); 32 } 33 34 //带参数的成员方法 35 public void jiSuan(int n) 36 { 37 int result = 0; 38 for (int i=1;i<=n;i++) 39 { 40 result+=i; 41 } 42 //输出结果 43 System.out.println(result); 44 } 45 46 //计算两个数的和 47 public void jiSuan(int num1,int num2) 48 { 49 int result = 0; 50 result = num1+num2; 51 System.out.println(result); 52 } 53 }
带返回结果的成员方法
1 public class example1 2 { 3 public static void main(String []args) 4 { 5 Person p1 = new Person(); 6 int res = p1.add(12,24); 7 System.out.println(res); 8 System.out.println(p1.add(12,24)); 9 } 10 } 11 12 13 class Person 14 { 15 //返回类型一定要和public后的返回数据类型一致 16 public int add(int num1,int num2) 17 { 18 return num1 + num2; //返回结果 19 } 20 }
注意:
- 两个成员方法如果只有返回类型不同的话,是不能通过编译的
- 不能将空类型进行赋值
- returen 的作用是把表达式的值返回给注调用方法,当然也可以返回
类成员方法的声明
类成员方法——声明
public int test ( int a ); //方法声明
方法声明和定义的区别是,方法声明没有函数体,声明只是说明有这个函数
//声明的格式 public int test (int a);
访问修饰符 数据类型 函数名 (参数列表);
类的成员方法的——特别说明
一、方法的参数列表可以是多个,并且参数列表的类型也可以是任意的
二、调用某个成员方法的时候,传入的实参要和形参的类型相匹配
例如:
1 public class example1 2 { 3 public static void main(String []args) 4 { 5 Person p1 = new Person(); 6 System.out.println(p1.add(2,2.3,4.5)); 7 } 8 } 9 10 11 class Person 12 { 13 //public double add(int num1.float num2,float num3) 14 //会报错,因为穿的参数是2,2.3和4.5,小数默认是double类型,损失精度报错 15 public double add(int num1,double num2,double num3) 16 { 17 return num1+num2+num3; 18 } 19 }
练习:
- 1、编写一个成员函数,从键盘输入一个整数(1 - 9),打印出对应的乘法表
- 2、编写函数,使给定的一个二维数组(3 x 3)转置(横坐标和纵坐标对调)
1 2 3 ——> 1 4 7
4 5 6 ——> 2 5 8
7 8 9 ——> 3 6 9 - 3、设计计算机类
- 4、模拟一下马里奥
构造方法(函数)
构造方法使类的一种特殊方法,它的主要作用是完成对新对象的初始化(闯进新对象时,给新对象几个默认值)。它有几个特点
- 方法名和类名相同
- 没有返回值
- 在创建一个类的新对象是,系统会自动调用该类的构造方法完成对新对象的初始化
1 public class example1 2 { 3 public static void main(String []args) 4 { 5 //Person p = new Person(); 6 //在加入了构造方法后,不加参数的声明会报错 7 Person p1 = new Person(1,"rotk"); 8 System.out.println(p1.age); 9 System.out.println(p1.name); 10 } 11 } 12 13 14 class Person 15 { 16 int age; 17 String name; 18 public Person(int age,String name) 19 { 20 age=age; //前面是成员属性,后面是传进来的值 21 name=name; 22 } 23 24 }
注意:一个类可以指定多个不同的构造方法,例如
1 public class example1 2 { 3 public static void main(String []args) 4 { 5 //因为有两个构造方法,所以调用哪个构造方法是由传递几个参数决定的 6 Person p1 = new Person(7); 7 Person p2 = new Person(2,"小白"); 8 } 9 } 10 11 12 class Person 13 { 14 int age; 15 String name; 16 //构造方法一 17 public Person(int age,String name) 18 { 19 System.out.println("我是构造一"); 20 age=age; //前面是成员属性,后面是传进来的值 21 name=name; 22 } 23 //构造方法二 24 public Person(int age) 25 { 26 System.out.println("我是构造二"); 27 age = age; 28 } 29 30 }
默认构造方法
如果程序员没有定义构造方法,系统会自动生成一个默认的构造方法。
//Person类中的默认构造方法 Person () { //nothing } //当创建一个Person对象时 Person perl=new Person; //默认的构造方法(函数)就会被自动调用
如果程序员写了一个构造方法后,这个默认的构造方法就没了,但可以自己把这个默认构造方法写回来,就可以不加参数创建对象了
构造方法小节
- 构造方法名和类名相同,如果不相同就不是构造方法
- 构造方法没有返回值,如果有返回值就不是构造方法
- 主要作用是完成新对象的初始化
- 在创建新对象时,系统自动的调用该类的构造方法
- 一个类可以有多个构造方法,但是不能完全相同
- 每个类都有一个默认的构造方法
一般来说构造方法的作用就是去初始化你的成员变量,不干别的事