面向对象

-------android培训 java培训  、期待与您交流-------

面向对象
 
面向对象的理解 
面向对象是相对面向过程而言,面向过程,强调的是功能行为
面向对象和面向过程都是一种思想
面向对象,将功能封装进对象,强调具备了功能的对象。
面向对象是基于面向过程的。
面向对象的三个特征:封装继承多态
 
类与对象的关系 
类:就是对现实生活中事物的描述
对象:就是这类事物,实实在在存在的个体
想要描述:提取对象中共性内容,对具体的抽象
描述时:这些对象的共性有,姓名,年龄,性别,学习Java功能。
描述在Java中是用类的形式来体现的,映射到Java中,描述就是class定义的类。
对象在Java中是通过new操作符所产生的一个实体,这个实体在堆内存中。
 
成员变量和局部变量 
作用范围:
成员变量作用于整个类中。
局部变量作用于函数或者语句中。
在内存中的位置:
成员变量:在堆内存中,因为对象的存在,才在内存中存在
局部变量:在栈内存中。
 
匿名对象 
匿名对象是对象的简化形式
匿名对象两种使用情况:
a   当对对象方法仅进行一次调用时
b   匿名对象可以作为实际参数进行传递
 
封装
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
好处:将变化隔离,便于使用,提高重用性,提高安全性。
封装原则:
1  将不需要对外提供的内容都隐藏起来。
2  把属性都隐藏,提供公共方法对其访问。
private关键字
是一个权限修饰符,用于修饰成员(成员变量和成员函数)
被私有化的成员只在本类中有效
常用于将成员变量私有化,对外提供对应的set和get方法对其进行访问,提高对数据访问的安全性。

构造函数
对象一被建立(通过new关键字),就会调用与之相应的构造函数,构造函数的作用就是给对象进行初始化。
特点:
1. 函数名与类名相同
2. 不用定义返回值类型
3. 不可以写return语句
注意:
1. 默认构造函数的特点。
         默认构造函数是隐式的。
         默认构造函数是空参数的构造函数。
         默认构造函数的权限和所属类一致,随着类权限的变化而变化。
2. 多个构造函数是以重载的形式存在的。
3. 当一个类中没有定义构造函数时,系统会默认给该类加入一个空参数的构造函数(默认构造函数)。
    当自定义了构造函数后,默认的构造函数就没有了。
构造函数和一般函数的区别:
写法不同
运行不同:
      构造函数是在对象一建立(new)就运行,给对象初始化
      一般函数是对象调用才执行,给对象添加对象具备的功能。
      一个对象建立,构造函数只运行一次。
      一般函数可以被该对象调用多次。
什么时候定义构造函数呢?
当分析事物时,该事物存在就具备一些特性或者行为,那么将这些内容定义在构造函数中。
 
构造代码块
构造代码块中定义的是不同对象共性的初始化内容。
作用:给对象进行初始化(对象一建立就运行,而且优先于构造函数)
构造代码块和构造函数的区别:
      构造代码块是给所有对象进行统一初始化。
      构造函数是给对应的对象初始化。
 
this关键字
this: 代表本类的对象,
this代表它所在函数所属对象的引用
可简单理解为:哪个对象在调用this所在的函数,this就代表哪个对象。
this的应用:
1    当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
2    但凡本类功能内部使用了本类对象,都用this表示
 
this关键字在构造函数间调用
this语句:用于构造函数之间互相调用
                 构造函数之间在互相调用时只能使用this
                 this语句只能定义在构造函数的第一行。因为初始化要先执行。
示例代码
class Person {
	private String name;
	private int age;
	Person(){
	}
	Person(String name){
		this.name = name;
	}
	Person(String name,int age){
		// this.name = name;
		this(name);
		this.age = age;
	}
}
class Demo{
	public static void main(String[] args){
		Person p = new Person("lisi",30);
	}
}

Static关键字
用于修饰成员(成员变量和成员函数)
被修饰后的成员具备以下特点:
1   随着类的加载而加载,随着类的消失而消失,生命周期最长。
2   优先于对象存在:静态是先存在的,对象是后存在的。
3   被所有对象所共享
 可以直接被类名调用: 类名.静态成员
实例变量(对象的变量)和类变量(static修饰的变量)的区别:
1      存放位置:
        类变量随着类的加载而存储在方法区中。
        实例变量随着对象的建立而存储在堆内存中。
2      生命周期:
        类变量生命周期最长,随着类的消失而消失。
        实例变量生命周期随着对象的消失而消失。
静态的使用注意事项:
1      静态方法只能访问静态成员。
        非静态方法既可以访问静态成员也可以访问非静态成员。
2      静态方法中不可以定义this和super关键字
3      主函数是静态的
静态的利弊:
利: 对对象的共享数据进行单独空间的存储,节省空间。
         可以直接被类名调用。
弊: 生命周期过长。
         访问出现局限性。(只能访问静态)
静态什么时候使用:(重点)
从两方面入手:因为静态修饰的内容有成员变量和成员函数。
1       何时定义静态变量(类变量)
         当对象中出现共享数据(是属性值而不是属性)时,该数据需要被静态所修饰
         对象中的特有数据要定义成非静态存储在堆内存中。
2       何时定义静态函数
         当功能内部没有访问到非静态数据(对象特有数据)时,该功能可以定义成静态的。
示例代码:
class Person {
	String name;
	public static void show() {
		System.out.println("haha");
	}
}
class Demo {
	public static void main(String[] args) {
		Person p = new Person();
		p.show();
		Person.show();
	}
}
//注释:此例中show方法并未调用name属性(非静态数据),
//这个时候需要把show方法定义成静态的通过person.show()直接调用,
//而不必new一个person对象,再通过对象调用show()方法

静态代码块
随着类的加载而执行,只执行一次,并优先于主函数,用于给类进行初始化
static{
    静态代码块中的执行语句;
}
对象的初始化过程
Person p = new Person("zhangsan",20);
代码执行顺序:
1,因为new用到person.class文件,所以会先找到person.class文件并加载进内存。
2,执行该类中的static代码块,如果有的话,给person.class类进行初始化。
3,在堆内存中开辟空间,分配内存地址。
4,在堆内存中建立对象的特有属性,并进行默认初始化。
5,对属性进行显示初始化。
6,对对象进行构造代码块初始化。
7,对对象进行对应的构造函数初始化。
8,将内存地址付给栈内存中的p变量。

 

对象调用成员过程


 
多态
 
定义:某一类事物的多种存在形态。
例:动物中猫,狗。
猫这个对象对应的类型是猫类型
猫 x = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。
动物 y = new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向了子类对象。
 
多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
多态的前提
必须是类与类之间有关系,要么继承,要么实现。
通常还有一个前提:存在覆盖。
多态的好处: 多态的出现大大的提高程序的扩展性。
多态的弊端: 提高了扩展性,但是只能使用父类的引用访问父类中的成员。
使用多态的注意事项
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。
在运行时期:参阅引用型变量所指向的对象中是否有调用的方法。
 
多态转型:
//多态转型演示代码
abstract class Animal1 {
	abstract void eat();
}
class Cat1 extends Animal {
	public void eat() {
		System.out.println("吃鱼");
	}
	public void cathMouse() {
		System.out.println("抓老鼠");
	}
}
class Dog1 extends Animal {
	public void eat() {
		System.out.println("吃骨头");
	}
	public void kanJia() {
		System.out.println("看家");
	}
}
class DuoTaiDemo2 {
	public static void main(String[] args) {
		Animal a = new Cat();// 类型提升,向上转型。
		a.eat();
		// 如果想要调用猫的特有方法时,如何操作?
		// 强制将父类的引用,转成子类类型,向下转型。
		Cat c = (Cat) a;
		// c.catchMouse();
		// 千万不要出现这样的操作,就是将父类对象转成子类类型。
		// 我们能转换的是父类应用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。
		// 多态自始自终都是子类对象在做着变化。
		// Animal a = new Animal();
		// Cat c = (Cat)a;
		function(new Cat());
		function(new Dog());
	}
	public static void function(Animal a)// Animal a =new Cat();
	{
		a.eat();		
		//if(a instanceof Animal){ System.out.println("haha"); } else
		if (a instanceof Cat) {
			Cat c = (Cat) a;
			// c.catchMouse();
		} else if (a instanceof Dog) {
			Dog c = (Dog) a;
			c.kanJia();
		}
	}
}
多态中成员的特点
1   在多态中,非静态成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
2   在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
3   在多态中,静态成员函数的特点:
无论编译和运行,都参考左边。
 
继承

继承的概述:将事物共性描述提取出来,单独进行描述
继承的特点
1, 提高了代码的复用性。
2, 让类与类之间产生了关系,有了这个关系,才有了多态的特性。
3, 必须是类与类之间有所属关系才可以继承,所属关系 is a .
4, Java只支持单继承,不支持多继承。
因为多继承容易带来安全隐患:
当多个父类中定义了相同功能,当功能内容不同时,不确定要运行哪一个。
但是Java中保留这种机制,并用另一种体现形式来完成表示,多实现。
5,   Java支持多层继承,也就是一个继承体系
如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。
通过了解共性功能,就可以知道该体系的基本功能,该体系已经可以基本使用了。
那么在具体调用时,要创建最子类的对象,为什么呢?
一是因为有可能父类不能创建对象。
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。
简单一句话:查阅父类功能,创建子类对象使用功能。
 
子父类中成员的特点
子父类出现后,类中成员的特点:
1,子父类中的变量
如果子类中出现非私有的同名成员变量时,
子类要访问本类中的变量,用this
子类要访问父类中的同名变量,用super
super的使用和this的使用几乎一致
this代表的是本类对象的引用。
super代表的是父类对象的引用。
2,子父类中的函数
函数覆盖
当子类出现和父类一模一样(返回值类型,函数名,参数列表都相同)的函数时,子类对象调用该函数,会运行子类函数的内容。
如同父类的函数被覆盖一样。这种情况是函数的另一个特性:重写(覆盖)

当子类继承父类,沿袭了父类的功能,到子类中。
但是子类虽具备该功能,但是功能的内容却和父类不一致。
这时,没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能内容。
覆盖的注意事项:
1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
2,静态只能覆盖静态。
注意:
重载:只看同名函数的参数列表,不看返回值类型。
重写:子父类方法要一模一样,返回值类型也必须一致。
3,子父类中的构造函数
在对子类对象进行初始化时,父类的构造函数也会运行。
那是因为子类的构造函数默认第一行有一条隐式的语句 super();
super():会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都有一个隐式super();语句。
为什么子类一定要访问父类中的构造函数。
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义显式super语句的方式来指定。
注意:super语句一定定义在子类构造函数的第一行。
子类的实例化过程
子类中所有的构造函数,默认都会访问父类中空参数的构造函数。
因为子类每一个构造函数内的第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,
子类中至少会有一个构造函数会访问父类中的构造函数。
final关键字
final:最终,作为一个修饰符。
1,可以修饰类,函数,变量。
2,被final修饰的类不可以被继承,为了避免被继承,被子类复写功能。
3,被final修饰的方法不可以被复写。
4,被final修饰的变量是一个常量,只能被赋值一次,既可以修饰成员变量,也可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字,方面阅读
而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果
由多个单词组成。单词间通过_连接。
5,内部类定义在类中的局部位置上,只能访问该局部被final修饰的局部变量。
抽象类(abstract)
当多个类中出现相同功能,但是功能主体不同。
这是可以进行向上抽取,只抽取功能定义,而不抽取功能主体。
抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。这些不确定的部分,也是该事物的功能,需要明确出现,但是无法定义主体。通过抽象方法表示。
抽象类比一般类多了个抽象函数,就是在类中可以定义抽象方法,抽象类不可以实例化
 抽象类的特点:
 1,抽象方法一定在抽象类中。
 2,抽象方法和抽象类都必须被abstract关键字修饰。
 3,抽象类不可以用new创建对象,因为调用抽象方法没意义。
 4,抽象类中的抽象方法要被调用,必须由子类复写起所有的抽象方法后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。 
abstract class Student{
	abstract void study()
	//abstract void study();
}
class BaseStudent extends Student{
	void study(){
		System.out.println("base study");
	}
}
class AdvStudent extends Student{
	void study(){
		System.out.println("adv study")
	}
}
class AbstractDemo{
	public static void main(String[] args){
		//new Student();
		new BaseStudent().study();
	}
}
接口(interface)
当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
接口中的成员修饰符是固定的。
成员常量:public static final
成员函数:public abstract
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
接口定义时,格式特点:
1,接口中常见定义:常量,抽象方法。
2,接口中的成员都有固定修饰符。
常量:public static final
方法:   public abstract
注:接口中的成员都是public的。
接口不可以创建对象,因为有抽象方法。
需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化,否则子类是一个抽象类。
接口可以被类多实现,也是对多继承不支持的转换形式,java支持多实现。
接口的特点:
接口是对外暴露的规则。
接口是程序的功能扩展。
接口可以用来多实现。
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
接口与接口之间可以有继承关系。

包(package)
对类文件进行分类管理
给类提供多层命名空间
写在程序文件的第一行
类名的全称是:包名.类名
包也是一种封装形式
 
包与包之间访问
包与包之间进行访问,被访问的包中的类以及类中的成员,需要被public修饰。
不同包中的子类还可以直接访问父类中被protected权限修饰的成员。
包与包之间使用的权限只有两种:public和protected
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值