面向对象一
1.1 概述
面向对象一种编程思想,是由面向过程发展而来。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。
1.2 面向过程
强调的是功能行为,面向过程”是一种以过程为中心的编程思想。“面向过程”他们不支持丰富的“面向对象”特性(比如继承、多态),就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
1.3 面向对象的优点
1. 符合人们思考习惯,可以将复杂的事情简单化将程序员从执行者转换成了指挥者。
2. 信息隐藏,提高了程序的可维护性和安全性
3. 提高了程序的可重用性
1.4 面向对象的三大特征
面向对象具备如下3大特征:
1.封装(encapsulation)
2.继承(inheritance)
3.多态(polymorphism)
2.类与对象的关系
2.1 对象
2.1.1 什么是对象
概念:描述现实世界,就是描述事物的属性和行为。现实世界的每个事物都可以理解为对象。即万物皆对象。
2.1.2 对象的特点
对象(object)代表现实世界中可以明确标识的一个实体。例如:一个学生、一张桌子、一间教室,一台电脑都可以看做是一个对象。即万物皆对象.
每个对象都有自己独特的属性和行为。
2.2 类
2.2.1 类的定义
概念:使用计算机语言就是不断的在描述现实生活中的事物。java中描述事物通过类的形式体现,类是具体事物的抽象,是概念上的定义。对象即是该类事物实实在在存在的个体。
类与对象的关系如图
可以理解为:
类就是汽车的图纸
一辆汽车就是根据汽车生产的对象
2.2.2 类与对象
1.面向对象的java语言使用类对现实世界进行描述;
2.类是图纸,模板;
3.java的类就是现实世界的事物的映射.。
1) 成员变量-->(属性)
2) 成员方法--> (行为)
4.java中的对象就是依据类产生的实体。
5.总结
1) java中先有类,后有对象。
2) 定义:java类就是定义类的成员即成员变量和成员方法。
2.3 成员变量与局部变量
2.3.1 局部变量
1) 方法中,参数列表中,语句中。
2) 必须给初始化值,没有初始值,不能使用
3) 在栈内存中
2.3.2 成员变量
1.属于类的成员,直接定义在类中;
2.有默认的初始化值;
1) 整数byte、short、int、long =0;
2) char='\uoooo';
3) boolean =flase;
4) String =null;
5) 类类型 =null;
6) 数组 =null;
3.在堆内存中。
2.4 代码实例
项目名称
* 需求:使用java或.NET描述汽车车、修理工厂两个类,车具备名字、颜色、*数三个属性、车具备跑的行为,
车在跑的时候应该判断是否够四个*,如果够四个*可以跑起,否则送去修车厂维修。
修车厂具备,名字、地址、电话三个属性,具备修车的功能行为。*
Car类的代码
- /**
- * 汽车类的代码,有名字、颜色,车轮数等属性还有run()方法
- * */
- public class Car {
- private String name;
- private String color;
- private int wheelNum;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getColor() {
- return color;
- }
- public void setColor(String color) {
- this.color = color;
- }
- public int getWheelNum() {
- return wheelNum;
- }
- public void setWheelNum(int wheelNum) {
- this.wheelNum = wheelNum;
- }
- public Car(String name, String color, int wheelNum) {
- //super();
- this.name = name;
- this.color = color;
- this.wheelNum = wheelNum;
- }
- public void run(){
- System.out.println("一辆" + this.color +"色的,叫"+ this.name +"的"+ this.wheelNum + "轮汽车正在行驶" );
- }
- public Car(){}
- }
- package com.ping.project;
- /**
- * 需求:汽车维修厂的类,有名字,有地址,有电话
- * */
- public class CarRepair {
- private String name;
- private String address;
- private String phone;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- public String getPhone() {
- return phone;
- }
- public void setPhone(String phone) {
- this.phone = phone;
- }
- public CarRepair(String name, String address, String phone) {
- super();
- this.name = name;
- this.address = address;
- this.phone = phone;
- }
- public Car repairCar(Car car){
- if(car.getWheelNum() < 4){
- car.setWheelNum(4);
- System.out.println(car.getName()+ "已维修好!可以上路了");
- }
- return car;
- }
- public CarRepair(){}
- }
- //修车厂具备,名字、地址、电话三个属性,具备修车的功能行为
主方法
public class CarTest { /** * * * 需求:使用java描述汽车车、修理工厂两个类,车具备名字、颜色、*数三个属性、车具备跑的行为, * 车在跑的时候应该判断是否够四个*,如果够四个*可以跑起,否则送去修车厂维修。 * 修车厂具备,名字、地址、电话三个属性,具备修车的功能行为。* * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //新建4个汽车对象 Car car1 = new Car("小绵羊一号","红" ,4); Car car2 = new Car("小绵羊二号","蓝" ,3); Car car3 = new Car("小绵羊三号","黑" ,4); Car car4 = new Car("小绵羊四号","白" ,4); //新建一个汽车维修类 CarRepair cr = new CarRepair(); //一个对象数组,将所有的汽车类包含其中 Car [] cars ={car1 , car2 , car3, car4}; //循环输出汽车类的方法 for(int i = 0 ; i < cars.length ; i ++){ //判断若车轮小于4个则送汽车维修厂维修 if(cars[i].getWheelNum() < 4){ System.out.println(cars[i].getName() + "只有" + cars[i].getWheelNum() + "个*需要维修!"); cr.repairCar(cars[i]); } //调用汽车run()方法 cars[i].run(); } } } [java] view plaincopy 输出: [java] view plaincopy 一辆红色的,叫小绵羊一号的4轮汽车正在行驶 小绵羊二号只有3个*需要维修! 小绵羊二号已维修好!可以上路了 一辆蓝色的,叫小绵羊二号的4轮汽车正在行驶 一辆黑色的,叫小绵羊三号的4轮汽车正在行驶 一辆白色的,叫小绵羊四号的4轮汽车正在行驶
2.5 匿名对象
2.5.1 概念
创建的对象都有名字,叫做非匿名对象。如果这个对象没有名字就叫做匿名对象。
2.5.2 匿名对象的简单演示
用上例的代码来举例
public class CarTest { /** * * * 需求:使用java描述汽车车、修理工厂两个类,车具备名字、颜色、*数三个属性、车具备跑的行为, * 车在跑的时候应该判断是否够四个*,如果够四个*可以跑起,否则送去修车厂维修。 修车厂具备,名字、地址、电话三个属性,具备修车的功能行为。* * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // 新建一个汽车维修类 CarRepair cr = new CarRepair(); // 一个对象数组,将所有的汽车类包含其中 Car[] cars = { new Car("小绵羊一号", "红", 4), new Car("小绵羊二号", "蓝", 3), new Car("小绵羊三号", "黑", 4), new Car("小绵羊四号", "白", 4) }; // 循环输出汽车类的方法 for (int i = 0; i < cars.length; i++) { // 判断若车轮小于4个则送汽车维修厂维修 if (cars[i].getWheelNum() < 4) { System.out.println(cars[i].getName() + "只有" + cars[i].getWheelNum() + "个*需要维修!"); cr.repairCar(cars[i]); } // 调用汽车run()方法 cars[i].run(); } } } 输出: 一辆红色的,叫小绵羊一号的4轮汽车正在行驶 小绵羊二号只有3个*需要维修! 小绵羊二号已维修好!可以上路了 一辆蓝色的,叫小绵羊二号的4轮汽车正在行驶 一辆黑色的,叫小绵羊三号的4轮汽车正在行驶 一辆白色的,叫小绵羊四号的4轮汽车正在行驶输出效果一致!
3:内存结构图
1) new Car().num=5;
2) new Car().clor="blue";
两个new 是两个不同的对象,在堆内存中有不同的空间,相互不相互干扰。
4:匿名对象的使用
1) 当执行一次方法时可以使用匿名对象。执行完毕后;该对象就变成了垃圾。
new Car().run();
2) 执行方法时,可以将匿名对象作为实际参数,传递进去。
3.封装
3.1 概念
使对象的属性尽可能私有,对象的方法尽可能的公开。用private表示此成员属性为该类的私有属性。
自己总结: 封装其实就是先将属性或方法用private访问修饰符定义后,再使用public方法获得其访问权。
注:(如果不指明谁调用方法,则默认为this,区分实例变量和局部变量时一定要写this)。
3.2 封装的好处
1.隐藏了类的具体实现;
2.提高对象数据的安全性;
3.提高了程序的可维护性和安全性。
3.3 代码实例
要求:新建一个person类,类中有属性name,age,sex和一个sayHi()方法对其属性进行封装处理,在main()方法中赋值,并打印到sayHi()
public class TestPrivate { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Person p1 = new Person(); // 由下面代码可知访问Person的各个属性必须要通过其属性相应的方法 p1.setAge(18); p1.setName("胡志平"); p1.getName(); p1.getAge(); p1.setSex("男"); p1.sayHi(); } } class Person { // 封装后的name属性 private String name; // 封装后的age属性 private int age; private String sex; // 得到sex的值 public String getSex() { return sex; } // 设置sex的值 public void setSex(String sex) { // 在方法内设置筛选条件,以防错误数据录入 if (sex.equals("男") || sex.equals("女")) this.sex = sex; else System.out.println("性别只能填“男”与“女”"); } // 得到Name的值的方法 public String getName() { return name; } // 设置Name的值的方法 public void setName(String name) { this.name = name; } // 得到age的值 public int getAge() { return age; } // 设置age的值 public void setAge(int age) { if (age < 0 || age > 1000) System.out.println("请输入正确年龄"); else this.age = age; } public void sayHi() { System.out.println("我的名字是:" + name + ",性别是:" + sex + ",今年:" + age + "岁。"); } } 输出: 我的名字是:胡志平,性别是:男,今年:18岁。
4.构造函数
Java中通过构造函数确保对象的初始化,这是一个对象被创建时会被调用的特殊方法.在Java中通过构造方法,可以保证类的每个对象都可以初始化。
4.1 构造函数示例
class Person { String name; int age; // 构造函数 Person(String n, int a) { name = n; age = a; } //普通成员函数 void speak() { System.out.println("hah"); } }
4.2 构造函数的特点
1.函数名与类名相同;
2.不需要定义返回值和void 不同;
3.不可以定义return语句。
4.3 构造函数作用
1.用于给对象初始化
4.4 默认无参会构造函数
1.之前并没有定义构造函数,系统提供默认无参构造。
2.但如果用户自定义构造函数,则系统不再提供无参会构造方法。
4.5 构造函数的重载
1.函数有重载,构造函数是函数,那么也具备重载的特性;
2.多个构造函数以重载的形式体现。
代码实例:
class Person { String name; int age; //无参数构造函数 Person() { System.out.println("这是无参的构造函数"); } //有参数构造函数 Person(int a) { age = a; System.out.println("有参构造1"); } //有参数构造函数 Person(String n) { name = n; System.out.println("有参构造2"); } //有参数构造函数 Person(int a, String n) { age = a; name = n; System.out.println("有参构造"); } //普通函数 void speak() { System.out.println("hah"); } }
4.6 构造函数和普通函数的区别
1.写法不同,构造函数没有返回值和静态
2.运行
1) 构造函数,用于对象初始化。对象一建立就运行。
2) 普通函数,对象调用后才执行,是对象具备的功能。
3) 对象建立构造函数只运行一次,普通函数可以运行多次。
4.7 构造代码块
1. 格式示例{}
class Person { String name; int age; // 构造代码块,给所有对象进行初始化。 { System.out.println("这是构造代码块"); } // 无参数构造函数 Person() { System.out.println("这是无参的构造函数"); } // 有参数构造函数 Person(int a, String n) { age = a; name = n; System.out.println("有参构造"); } // 普通函数 void speak() { System.out.println("名字:"+name+" 姓名:"+age+"hah"); } }
2.作用
1) 给对象进行初始化。对象一建立就运行并且优先于构造函数。
2.与构造函数区别
1) 构造代码块和构造函数的区别,构造代码块是给所有对象进行统一初始化, 构造函数给对应的对象初始化。
2) 构造代码块的作用:把不同对象的共性内容,放到构造代码块中,统一初始化。
class Person{ String name; int age; // 构造代码块,给所有对象进行初始化。 { System.out.println("我是构造代码块"); } Person() { System.out.println("无参构造"); } Person(String n, int a, String g) { name = n; age = a; System.out.println("有参构造"); } void run() { System.out.println("我在跑。。。。"); } } class Demo9 { public static void main(String[] args) { System.out.println(); Person p1 = new Person(); Person p2 = new Person("jack", 1, "男"); } }
5.this关键字
5.1 this的意义
this代表所在函数所属对象的引用。因为函数需要被调用才会执行,当前的对象调用了它,所以this就代表所在函数所属对象的引用。
5.2 代码实例
需求: 需要构造函数间的调用
1.定义Person类
1) 有姓名年龄成员变量,有说话的方法。
2) 定义构造方法,无参的,多个有参的。
class Person { String name; int age; //无参数构造函数 Person() { System.out.println("这是无参的构造函数"); } //有参数构造函数 Person(int a) { age = a; System.out.println("有参构造1"); } //有参数构造函数 Person(String n) { name = n; System.out.println("有参构造2"); } //有参数构造函数 Person(int a, String n) { age = a; name = n; System.out.println("有参构造"); } //普通函数 void speak() { System.out.println("你好!"); } }
2.属性值还没有什么问题,但假设定义40个成员变量,第一个有参构造初始化20个变量,第二个有参构造初始化40个变量,这为属性赋值就显得非常麻烦了。
1) 第二个有参构造想要调用第一个有参构造。通过this关键字就可以解决该问题。
class Student { String name; String gender; int age; Student() {} Student(String name) { this(); this.name = name; } Student(String name, String gender, int age) { this(name); System.out.println(this); // Student@c17164 this.gender = gender; this.age = age; } void speak() { run(); System.out.println("姓名:" + name + " 性别:" + gender + " 年龄:" + age ); } void run() { System.out.println("我在跑。。。。"); } } class Demo2 { public static void main(String[] args) { Student p = new Student("jack", "男", 20); System.out.println(p); // Student@c17164 Student p2 = new Student("rose", "女", 18); System.out.println(p2); p.speak(); } }
注意:
1) this只能在非静态中(没有static修饰的)函数使用
2) 构造函数间相互调用必须放在构造函数的第一行,否则编译错误
3) 可以解决构造函数中对象属性和函数形参的同名问题。
6.static 关键字
6.1 static作用
为了实现对象之间重复属性的数据共享。
6.2 代码实例
1.定义Count类
1) 里面有一个静态修饰的成员变量;
2) 一个方法,调用一次成员变量减一。
public class SimpleDemo { public static void main(String args[]) { new Count().listCount(); new Count().listCount(); } } class Count { int count = 3; public void listCount() { System.out.println("还有" + --count + "个数字!"); } } class Count{ int count = 3 ; public void listCount(){ System.out.println("还有" + --count + "个数字!"); } 输出: 还有2个数字! 还有2个数字!而如果count是静态的呢?
public class StaticDemo { public static void main(String args[]) { new Count().listCount(); new Count().listCount(); } } class Count { static int count = 3; public void listCount() { System.out.println("还有" + --count + "个数字!"); } } 输出: 还有2个数字! 还有1个数字!
3)创建Count对象
1:分析内存
总结:每个对象都共用着相同的count的变量,staitc修改的变量随着类的产生而产生,static只会与相应的类同存。
6.3 static修饰类的成员
6.3.1 static修饰成员变量
1.非静态成员变量,需要创建对象来访问;
2.静态成员变量:使用类名直接调用,也可以通过对象访问。
6.3.2 static修饰成员方法
1.静态函数:使用类名直接调用,也可以通过对象访问
1)静态函数的特点:
[1] 静态函数中不能访问非静态成员变量,只能访问静态变量。
[2] 静态方法不可以定义this,super关键字.
[3] 因为静态优先于对象存在.静态方法中更不可以出现this
2.非静态函数:非静态函数中可以访问静态成员变量
class Person { String name; int age; String sex; //static 修饰成员变量 static String country = "中国"; Person() { } Person(String name, int age, String sex) { this.name = name; this.age = age; this.sex= sex; } void speak() { //非静态方法 //非静态方法可以访问静态成员 System.out.println("国籍:" + country ); System.out.println("国籍:" + country + " 姓名:" + name + " 性别:" + sex + " 年龄:" + age + " !"); } static void run() //静态方法 { System.out.println("国籍:"+country); //静态方法只能访问静态成员变量。 System.out.println("姓名:" +name); //静态方法访问非静态成员变量,编译报错。 this.speak();//静态方法中不可以出现this,编译报错 } }注意:
1:静态函数中不能使用非静态变量
2:非静态函数可以访问静态变量
6.3.3 静态函数的特点
静态函数不能访问非静态成员变量
6.3.4 静态成员变量的特点
1.静态成员变量可以直接被类名调用;
2.静态成员变量被所有实例(对象)所共享;
3.静态成员变量随着类的加载而加载,随着类的消失而消失。所以它的生命周期要比普通对象的实例变量长;
4.静态成员变量优先于对象存在;
静态成员是先存在,对象是后存在(对象需要创建)。
6.3.5 静态变量(类变量)和实例变量的区别
1.存放位置
1) 类变量随着类的加载而加载存在于方法区中;
2)实例变量随着对象的建立而存在于堆内存中。
2.生命周期
1)类变量生命周期最长,随着类的消失而消失;
2)实例变量生命周期随着对象的消失而消失。
6.4 静态的优缺点
1.优点:对象的共享数据进行单独空间的存储,节省空间 例如Person 都有国籍。该数据可以共享并且可以通过类名直接调用.
2.缺点:静态成员变量的生命周期过长,同时静态方法的访问出现局限性。(静态方法只能访问静态成员变量)
6.5 静态代码块
1:静态代码块
static
{
静态代码块执行语句;
}
2:静态代码块特点
随着类的加载而加载。只执行一次,优先于主函数。用于给类进行初始化。
public class PersonDemo { public static void main(String[] args) { // 访问静态成员 // 直接通过类名来调用 String country = Person.country; System.out.println(country); // 通过对象.成员的形式访问 Person p1 = new Person("john", 20, "男"); p1.country = "美国"; p1.speak(); } } class Person { String name; int age; String gender; // static 修饰成员变量 static String country = "中国"; static { System.out.println("这是静态代码块"); } { System.out.println("这是构造代码块"); } Person() { System.out.println("无参数构造"); } Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; System.out.println("有参数构造"); } // 非静态方法 void speak() { // 非静态方法可以访问静态成员 System.out.println("国籍:" + country); System.out.println("国籍:" + country + " 姓名:" + name + " 性别:" + gender + " 年龄:" + age + " !"); // 非静态方法可以调用静态方法 run(); } // 静态方法 static void run() { // 静态方法只能访问静态成员变量。 System.out.println("国籍:" + country); } } 输出: 这是静态代码块 中国 这是构造代码块 有参数构造 国籍:美国 国籍:美国 姓名:john 性别:男 年龄:20 ! 国籍:美国
6.4 main方法
6.4.1 格式
public static void main(String[] args){
}
6.4.2 概念
主函数是什么:主函数是一个特殊的函数,作为程序的入口,可以被jvm识别。
6.4.3 参数说明
主函数的参数说明:
public :代表该函数的访问权限是最大的。
static :代表主函数随着类的加载,就已经存在了。
void: 主函数没有具体的返回值
main : 不是关键字,是一个特殊的单词可以被jvm识别。
(String[] args) 函数的参数,参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组。
主函数的格式是固定的:jvm能够识别
jvm在调用函数是,传入的是new String[0];
可以在dos窗口中执行 java Demo5 hello world 给类Demo5的main方法传递2个参数,参数与参数之间通过空格隔开。
class Demo5 { public static void main(String[] args) { // 获取String[] args 数组长度 System.out.println(args.length); // 变量args数组 for (int x = 0; x < args.length; x++) { System.out.println(args[x]);} } } class MainTest { public static void main(String[] args) { // 字符串数组 String[] arr = { "good", "study", "java" }; // 调用Demo5类的main方法,传递参数。 Demo5.main(arr); } }
----------- android培训、java培训、java学习型技术博客期待与您交流! ------------