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

------<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"关系定义的都是该继承体系中扩展性的东西






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值