您的位置:首页 > 职场人生

黑马程序员---java基础----面向对象总结

2015-09-24 16:45 746 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

一、面向对象思想:

面向过程:关注步骤和过程

面向对象:关注的是对象
面向对象是基于面向过程的

(1)类的定义

手机事物:属性:
品牌 , 颜色 , 价格 .....行为:
打电话 , 发短信 , 打游戏 ....手机类:成员变量:
品牌(brand) , 颜色(color) , 价格(price) 成员方法: 打电话(call) , 发短信(sendMessage) , 打游戏(playGame)

class Phone {

// 成员变量
String brand = "三星";		// 品牌
String color = "白色";		// 颜色
int    price = 1999 ;		// 价格

// 成员方法
// 打电话(call)
public void call(String name){
System.out.println("给" + name + "打电话");
}

// 发短信(sendMessage)
public void sendMessage(String name){
System.out.println("给" + name + "发短信");
}

// 打游戏(playGame)
public void playGame(){
System.out.println("玩游戏....");
}

}


(2)类与对象

我们学习编程的目的? 为了模拟现实生活中的事物 .

如何描述现实生活中的事物呢?

学生:

姓名,年龄, 性别 ....

学习 , 吃饭 , 睡觉 ....

属性: 就是事物的描述信息

行为: 就是该事物可以做什么事情

而我们java语言的最小单位是一个类. 所以我们就找到了事物是java语言中的一个东西的对应关系.

事物类

属性 成员变量

行为 成员方法

成员变量: 和之前定义变量一样,只不过位置不同,在类中方法外

成员方法: 和之前定义方法一样,只不过去掉static(后面在讲解)

类: 是一组相关属性和行为的集合, 类是一个抽象的东西

对象: 就是该类的一个具体体现

举例:

学生 类

班长 对象

使用类:

创建对象: 格式:
类名 对象名 = new 类名();

访问成员变量的格式:
对象名.变量名 ;

访问成员方法的格式:
对象名.方法名(...)

创建对象的步骤:

Student s = new Student();

步骤:

(1): 加载Student的字节码文件到方法区

(2): 在栈内存中为s开辟空间

(3): 在堆内存中为new Student()开辟空间

(4): 给成员变量进行默认初始化

(5): 给成员变量进行显式初始化

(6): 通过构造方法对成员变量赋值

(7): 将堆内存中的地址值赋值给栈内存中的引用变量s

(3)一个对象的内存图



(4)局部变量和成员变量的区别:

a: 在类中的位置不同

局部变量: 在方法定义中或者方法声明上的变量

成员变量: 在类中方法外

b: 在内存中的位置不同

成员变量: 在堆内存

局部变量: 在栈内存

c: 生命周期不同

成员变量: 随着对象的创建而产生,随着对象的消失而消失

局部变量: 随着方法的调用而产生,随着方法的消失而消失

d: 初始化值的问题:

成员变量: 有默认值(系统给定)

局部变量: 没有默认值,必须对其赋值以后才能使用

变量的注意事项:

a: 局部变量可以和成员变量的名称一致

b: 变量在访问的时候,遵循一个原则"就近原则"

(5)java语言中的参数传递问题:

基本数据类型的参数传递,形式参数的改变对实际参数没有影响

引用数据类型的参数传递,形式参数的改变对实际参数是有直接影响的

引用数据类型: 数组 , 类 , 接口

如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。

class Demo {

public void show(int a){
System.out.println(a);
}

}

class Student {

public void method(){
System.out.println("student的method方法被调用了");
}

}

class StudentDemo {

// 以后在看到某一个方法上,需要一个类类型的变量.那么我们在调用的时候,需要传递的是一个该类的对象
public void function(Student s){		// Student s = new Student();
s.method();
}

}

// 测试类
class ArgsDemo {

public static void main(String[] args){

// 创建Demo对象
Demo d = new Demo();

// 调用方法
// int a = 20 ;

d.show(20);

System.out.println("----------------------------");

// 创建StudentDemo对象
StudentDemo sd = new StudentDemo();

// 创建Student对象
Student s = new Student();

sd.function(s);

}

}


(6)匿名对象: 就是没有名字的对象

匿名对象的作用:

a: 调用方法,仅仅调用一次的时候

b: 作为参数传递

class Student {

public void show(){
System.out.println("student的show方法被调用了");
}

}

class StudentDemo {

public void method(Student s){
s.show();
}

}

// 测试类
class NoNameDemo {

public static void main(String[] args){

// 创建Student对象
Student s = new Student();

// 调用show方法
s.show();
// s.show();

System.out.println("---------------------------");

// 匿名对象
// new Student();

new Student().show();
// new Student().show();		重新创建了一个对象和之前不一样

System.out.println("---------------------------");

// 创建StudentDemo对象
// StudentDemo sd = new StudentDemo();

// 调用method方法
// sd.method(s);

// 把匿名对象作为参数传递
// sd.method(new Student());

new StudentDemo().method(new Student());
}

}


二、面向对象的3个特征:

封装

继承

多态

面向对象开发

就是不断的创建对象,使用对象,指挥对象做事情。

(1)封装

我们在赋值的时候,发现有时候可以为负数.但是我们都知道年龄不能为负数.所以我们应该对数据做一个校验吧.

我们需要将校验放在Student类中还是PrivateDemo类中?应该放在Student类中.为什么呢?

PrivateDemo 是一个测试类,既然是测试类,那么我们就需要测试所有的数据,而不能将错误的数据进行过滤吧.

校验: 我们需要使用一个逻辑的判断.所以我们需要使用语句.语句只能写在方法中,所以我们需要在Student类中

编写一个方法.(作用: 是给age设置值)

我们在使用的时候,我们还可以通过成员变量直接对其赋值.这样不太友好.

我们需要其强制的使用方法来对age设置.言下之意,就是不能让外界直接访问成员变量age.

这时候java就给我们提供了一个关键字: private (私有的)

封装的思想:

是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

封装好处

隐藏实现细节,提供公共的访问方式

提高了代码的复用性

提高安全性。

封装原则

将不需要对外提供的内容都隐藏起来。

把属性隐藏,提供公共方法对其访问

a、private关键字的特点:

a: private是一个修饰符

b: 可以用来修饰成员变量和成员方法

c: 被private修饰的成员只能在本类中访问

// 学生类
class Student {

// 成员变量
String name ;	// 姓名
private int age	;		// 年龄

// 定义一个方法.作用: 是给age设置值
public void setAge(int a){
if(a > 120 || a < 0){
System.out.println("数据非法!!!");
}else {
age = a ;
}
}

// 成员方法
// 用来输出所有的成员变量
public void show(){
System.out.println(name);
System.out.println(age);
}

}

// 测试类型
class PrivateDemo {

public static void main(String[] args){

// 创建对象
Student s = new Student();

// 给成员变量赋值
s.name = "凤姐";
// s.age  = 38 ;
s.setAge(38);

// 调用show方法
s.show();

System.out.println("-------------------------");

// 创建学生对象
Student s2 = new Student();

// 给成员变量赋值
s2.name = "刘亦菲";
// s2.age = -27 ;
s2.setAge(-27);

// 调用show方法
s2.show();

}

b、this关键字:

我们在起名字的时候,要做到的"见名知意",但是现在没有做到"见名知意",所以我们需要更改一下下.

this关键字: 代表的是本类对象的一个引用, 谁调用我this就代表谁.

this的存在解决的问题: 当局部变量将成员变量隐藏的时候,我们就可以通过this来明确直接访问的是成员变量.

变量在访问的时候遵循一个就近原则,现在我们的局部变量的名称和成员变量的名称一致.

所以在赋值的时候,并没有涉及到成员变量.

而我们的目的是: 把传递进来的name赋值为成员变量的name

我们访问成员变量只能通过对象来进行访问,那么谁有可以代表当前类的一个对象呢?

这时候java就给我们提供了一个关键字: this

c、构造方法

特点:

(1): 方法名和类名相同

(2): 没有返回值类型,连void也没有

(3): 没有返回值

作用:

给成员变量赋值

注意事项:

(1): 当我们没有给出构造方法的时候,系统将会提供一个默认的无参的构造方法

(2): 当我们给出构造方法的时候,系统将不会提供一个默认的无参的构造方法

d、static关键字

特点:

(1): 随着类的加载而加载

(2): 优先于对象存在

(3): 被类的所有的对象所共享

(4): 可以通过类名调用.本身也可以通过对象名调用

建议使用类名调用

注意事项:

(1): 在静态的方法中不能存在this关键字

(2): 静态只能访问静态

e、代码块

概述: 在java中使用{}括起来的内容

分类: 局部代码块 , 构造代码块 , 静态代码块 , 同步代码块(多线程)

局部代码块:
位置在方法定义中

构造代码块: 位置在类中方法外 , 特点: 每创建一次对象都调用一次 , 并且优先于构造方法执行

静态代码块:
位置在类中方法外 , 前面添加一个static 特点: 随着类的加载而加载,只执行一次 ,优先于构造代码块

(2)继承

格式:class 子类名 extends 父类名 {}

好处:

(1): 提高了代码的复用性

(2): 提高了代码的维护性

(3): 让类与类产生了关系,是多态的前提

弊端:

让类与类产生了关系,增强了耦合性

特点:

(1): 只能是单继承 ,不能是多继承

(2): 可以使用多层继承

注意事项:

(1): 父类中私有的成员不能被子类继承

(2): 父类中的构造方法不能被子类继承,但是可以通过super去访问

(3): 不能为了部分功能去使用继承

继承中成员变量的访问特点:

变量在访问的时候遵循一个"就近原则"

查找顺序:

(1): 在子类的局部位置

(2): 在子类成员位置

(3): 在父类的成员位置找

(4): 报错

this和super的区别:

this: 表示是本类对象的一个引用,谁调用我this就代表谁

super:表示的是父类存储空间的一个标识(理解: 父类对象的运用)

成员访问格式:

成员变量

this.变量名
本类的成员变量

super.变量名
父类的成员变量

构造方法

this(...)
本类的构造方法

super(...)
父类的构造方法

成员方法

this.方法名(...) 本类的成员方法

super.方法名(...)父类的成员方法

继承中构造方法的访问特点:

子类在初始化的时候,默认去调用父类的无参的构造方法

所有的构造方法的第一句都是super()

注意事项:

this(...) 和 super(...)必须是构造方法第一行

Object:
所有的类都是直接的或者间接的继承自该类

继承中成员方法的访问特点:

查找顺序:

(1): 在子类中查找

(2): 在父类中查找

(3): 报错

方法重写与方法重载的区别

方法重写: 子类中出现了和父类中一模一样的方法(方法名, 返回值类型 , 参数列表)

方法重载: 在同一个类中,允许同时存在一个以上的同名方法只要它们的参数列表不同, 与返回值无关

final关键字

特点:

final(最终的)

修饰类 被修饰的类不能被继承

修饰变量 被修饰的变量其实是一个常量

引用类型 指的是地址值不能被改变

基本类型 指定是值不能被改变

修饰方法 被修饰的方法不能被子类重写

final的初始化时机问题:

a: 只能被赋值一次

b: 在构造方法结束前赋上值就OK了(非静态的)

// 动物
class Animal {

// 成员变量
private String name ;
private int		age ;
private String color ;

// 构造方法
public Animal(){}

public Animal(String name , int age , String color){
this.name = name ;
this.age = age ;
this.color = color ;
}

// 提供get和set方法
public void setName(String name){
this.name = name ;
}

public String getName(){
return name ;
}

public void setAge(int age){
this.age = age ;
}

public int getAge(){
return age ;
}

public void setColor(String color){
this.color = color ;
}

public String getColor(){
return color ;
}

// 成员方法:	吃饭 , 睡觉
public void eat(){
System.out.println("吃饭了....");
}

public void sleep(){
System.out.println("睡觉");
}

}

// 猫
class Cat extends Animal {

// 给出构造方法
public Cat(){}

public Cat(String name , int age , String color){
super(name , age , color);
}

// 抓老鼠
public void catchMouse(){
System.out.println("哦,抓到了一只老鼠...");
}

}

// 狗
class Dog extends Animal{

// 给出构造方法
public Dog(){}

public Dog(String name , int age , String color){
super(name , age , color);
}

// 看门
public void lookDoor(){
System.out.println("狗正在看门..");
}

}

// 测试类
class ExtendsTest3  {

public static void main(String[] args)  {

// 创建一个狗对象
Dog d1 = new Dog();

// 给成员变量赋值
d1.setName("旺财");
d1.setAge(3);
d1.setColor("黄色");

// 输出成员变量
System.out.println(d1.getName() + "----" + d1.getAge() + "---" + d1.getColor());

System.out.println("-------------------------------");

// 创建对象
Dog d2 = new Dog("哮天犬" ,45 , "黑色" );

// 输出成员变量
System.out.println(d2.getName() + "----" + d2.getAge() + "---" + d2.getColor());

System.out.println("-------------------------------");

d2.eat();
d2.sleep();
d2.lookDoor();
}
}


(3)多态

前提:

(1): 需要有继承

(2): 需要有方法重写,没有方法重写也是可以的,但是没有意义

(3): 父类的引用指向子类对象

Fu f = new Zi();

多态中成员的访问特点:

成员变量: 编译看左边, 运行看左边

成员方法: 编译看左边 , 运行看右边

静态成员方法:
编译看左边 , 运行看左边

好处:

(1): 提供了代码的维护性(继承)

(2): 提供了代码的扩展性(多态)

弊端:

不能访问子类特有的功能

向下转型: 就是把父类的引用强制转换成子类的引用Zi zi = (Zi)f ;

向上转型: 父类的引用指向子类对象Fu f = new Zi();

抽象类

特点:

(1): 抽象类格式:
abstract class 类名 {}

抽象方法的格式:
public abstract 返回值类型 方法名(...);

(2): 抽象类中可以有非抽象方法,也可以有抽象方法,如果一个类中存在抽象方法,那么就需要将该类定义为抽象类

(3): 构造方法

有, 用于子类在访问数据的时候初始化

(4): 抽象类不能对其进行直接实例化,但是可以对其进行间接的实例化(多态的形式)

(5): 抽象类的子类

a: 可以是抽象类

b: 可以是具体的类,但是这个具体的类需要重写抽象类中的抽象方法

成员特点:

(1): 成员变量可以是变量,也可以是常量

(2): 构造方法有 , 用于子类在访问数据的时候初始化

(3): 成员方法可以是抽象方法,可以是非抽象方法

面试题:

abstract不能和那些关键字进行共存?

private冲突

final冲突

static无意义

接口

特点:

(1): 定义接口的格式
interface 接口名{}

(2): 类实现接口的格式
class 类名 implements 接口名{}

(3): 接口不能对其进行直接的实例化,但是可以通过多态的形式对其进行间接的实例化

(4): 接口的子类

a: 可以是抽象类

b: 可以是非抽象类,该类必须重写接口中的抽象方法

(5): 接口中没有构造方法,并且接口中的方法都是抽象方法

成员特点:

成员变量 只能常量,存在默认的修饰符public static final

构造方法 没有

成员方法 只能是抽象方法,存在默认的修饰符public abstract

类与类 , 类与接口, 接口和接口的关系

类与类: 继承关系(extends),只支持单继承,不支持多继承 , 但是可以多层继承

类与接口: 实现关系(implements) , 可以是单实现,也可以是多实现,并且一个类可以在继承一个类的同时,实现多个接口

接口和接口:
继承关系(extends),可以是单继承,也可以是多继承

抽象类和接口的区别:

a: 成员区别

抽象类

成员变量 可以是变量,也可以是常量

构造方法 有

成员方法 可以是抽象方法,也可以非抽象方法

接口

成员变量 只能是常量public static final

构造方法 没有

成员方法 只能是抽象方法public abstract

b: 关系区别

类与类: 继承关系(extends),只支持单继承,不支持多继承 , 但是可以多层继承

类与接口: 实现关系(implements) , 可以是单实现,也可以是多实现,并且一个类可以在继承一个类的同时,实现多个接口

接口和接口:
继承关系(extends),可以是单继承,也可以是多继承

c: 设计理念

抽象类 体现的是"is a"关系定义的都是该继承体系中共性的内容

接口 体现的是"like a"关系定义的都是该继承体系中扩展性的东西
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: