面向对象一
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学习型技术博客期待与您交流! ------------