------- android培训、java培训、期待与您交流! ----------
(1)面向对象概念
定义:面向对象(Object Oriented,OO)是软件开过过程中使用一种思维方式。
•面向过程:强调功能行为,关注完成的过程
•面向对象:将功能封装进对象,强调具备了功能的对象,不关注过程
•面向对象与面向过程都是一种思想
•面向对象是基于面向过程的
特点:
•是一种更符合人们思考习惯的思想。
•可以将复杂的事情简单化。
•将程序由执行者转换成了指挥者。
面向对象完成需求:
•明确开发功能需求。
•查找具有该功能的类。
•如果不存在满足功能的类,则定义这样的类。
•创建该类对象,使用对象完成功能。
(2)类与对象
类的概念
:具有相同特征(属性)和行为(功能)的一类事物的抽象。
•如:人类有身高,体重等属性,有说话,打球等行为。
•如:动物类有年龄,性别等属性,有吃饭,睡觉等行为。
类在Java中代码的体现形式:
•使用class(类)来抽象一个现实生活中的事物
-定义
成员变量对应事物的属性
-定义
成员函数对应事物的功能
•在Java开发的过程中,定义类就是定义类中成员变量与成员属性,完成这个类功能的过程。
•定义格式:
class 类名
{
数据类型 成员变量名;
成员函数{}
}
对象:类的实体
•如:人类是类的定义,张三李四便是人类的实体对象。
•如:水果类是类的定义,苹果橘子是水果类的实体对象。
类与对象的关系:
•类是抽象概念,对象是类的具体实例。
•一个类可以有多个对象。一个对象只属于一个类。
对象创建格式:
数据类型 变量名(对象名) =new 数据类型(参数);
对象的使用:
•成员变量的访问:
对象名.属性名
•成员函数的调用
对象名.函数名(参数)
成员变量
•定义位置:类中,整个类中均可以访问。
•内存:成员变量随着对象的建立而建立,存在于对象所在的堆内存中。
•默认值:成员变量有默认值。
•回收:随着对象的回收而回收。
局部变量
•定义位置:定义域局部范围,如函数内,语句内等。
•内存:局部变量存在于栈内存中。
•默认值:没有默认值。
•回收:随着作用域结束而回收,通常为语句或函数范围。
变量访问原则:就近原则
(4)构造函数
定义:用来创建实例对象时调用的方法。
格式特点:
•函数名与类名相同,与函数名标识符命名原则相悖
•不进行返回值类型的定义
•构造方法没有返回值
作用:
•为对象属性进行初始化
注意事项:
•如果没有手动给出构造方法,则java会为我们提供一个空参的构造方法。
•如果手动地给出任意构造方法,则java均不会再为我们提供构造方法。
•多个构造方法使用重载的方式给出。
创建对象使用对象的步骤:
•定义引用类型变量用来引用对象
•使用new关键字与构造方法完成对象创建
•在构造方法的同时对成员变量赋值
•使用get/set方法操作成员变量
•使用对象名.方法名(参数)调用对象函数
创建对象时JVM所作动作:
•栈内存开辟空间存储引用变量
•使用new创建内存空间
•调用构造方法
•成员变量默认初始化
•成员变量显示初始化
•构造函数初始化
•对象创建结束,将地址赋值给引用变量
(5)封装(encapsulation)
定义:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
优点:
•将变化隔离
•便于使用
•提高重用性
•提高安全性
原则:
•将不需要对外提供的内容都隐藏起来。
•把属性都隐藏,提供公共方法对其访问。
private关键字:
是一个权限修饰符。
用于修饰成员(成员变量和成员函数)
被私有化的成员只在本类中有效。
常用方式:将成员变量私有化,对外提供对应的set ,get方法对其进行访问。提高对数据访问的安全性。
this关键字:
定义:
•this代表其所属对象的引用。
•没有实例对象,this就没有意义。
this的使用:
•当在函数内需要用到调用该函数的对象时,就用this
-局部变量隐藏成员变量时,使用this区分。
-构造函数中第一行,用来调用本类其他重载的构造函数。
定义一个封装类的步骤:
•私有成员属性
•至少一个空参的构造方法
•普通方法
•公共的get/set方法通常手动放在最后
super关键字:代表父类的内存空间。使用super区分子父类所属。
•用法与this类似
•子类的构造方法中均有默认的super()
(6)继承(inheritance)
定义:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
•这多个类称为子类,单独这个类称为父类或者超类。
•子类可以直接访问父类中非私有的成员变量与成员方法。
格式:通过 extends 关键字让类与类之间产生继承关系
class SubDemo extends Demo{}
优点:
•
继承的出现提高了代码的复用性。
•
继承
的出现让类与类之间产生了关系
,
是
多态
的
前提
之一
。
弊端:使类与类之间产生了更强的耦合性
特点:
•java只支持单继承不支持多继承。
•java支持多层继承。
•任何类都直接或者间接继承自Object类。
注意事项:
•不要为了某个功能而去继承,需要满足”is a”的关系。
成员变量:访问满足就近原则
局部变量>成员变量>父类成员变量>父类的父类
成员方法:
•子类可以直接使用父类的非私有方法。
•当子父类方法一样时,方法重写。
构造方法:
•构造方法不继承,子类的构造默认调用父类构造。
•父类构造方法负责对成员变量初始化供子类对象使用,而不是创建父类对象。
•父类没有无参构造时,子类需要手动调用其他父类构造。
方法重写:
定义:子类中出现与父类一模一样的方法时,出现方法重写
•子类方法访问权限需要大于等于父类方法访问权限
•静态只能覆盖静态
•返回值类型:
•基本类型/void:必须相同
•引用类型:子类返回值类型必须为父类返回值类型的子类
•函数名相同
•参数列表相同
应用:子类需要父类功能,但又在功能上又有多增加时,可以复写父类方法。子类比父类更强大。
注意事项:
•父类中私有方法不可以被覆盖。
•在子类中想调用父类自己的方法可以使用super关键字
继承练习:
/*
设计:人、餐厅员工、餐厅经理、厨师4个类。
强制要求:
本关系中存在两层继承关系
对于人类必须有吃饭、睡觉的方法,以及姓名,年龄的属性
对于员工必须有薪资属性与上班的方法,要求上班的方法内有System.out.println(“上班打卡”)。
对于餐厅经理与厨师除了上班打卡外,分别均有自己的上班方式:如经理上班的内容还包括处理客户矛盾等,
厨师上班的内容还包括炒菜。(要求使用方法重写)
*/
class Test
{
public static void main(String[] args)
{
//创建对象,使用对象调用方法
Manager m = new Manager("倪漫天",18,28000);
m.work();
System.out.println(m.getName()+":"+m.getAge()+"------"+m.getMoney());
}
}
//定义人类
class Person
{
//对于人类必须有吃饭、睡觉的方法,以及姓名,年龄的属性
//定义人类属性
private String name;
private int age;
//定义人类构造
public Person() {}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
//定义普通方法
public void eat() {
System.out.println("我吃了");
}
public void sleep() {
System.out.println("我睡了");
}
//加入getters与Setters
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;
}
}
//对于员工必须有薪资属性与上班的方法,要求上班的方法内有System.out.println(“上班打卡”)。
//定义员工子类
class YuanGong extends Person
{
//定义子类特有的属性
private int money;
//定义员工构造
public YuanGong() {}
public YuanGong(String name,int age,int money) {
super(name,age);
this.money = money;
}
//定义普通方法
public void work() {
System.out.println("上班打卡");
}
//加入getters与Setters
public void setMoney(int money) {
this.money = money;
}
public int getMoney() {
return money;
}
}
//对于餐厅经理与厨师除了上班打卡外,分别均有自己的上班方式:如经理上班的内容还包括处理客户矛盾等,
//厨师上班的内容还包括炒菜。(要求使用方法重写)
class Manager extends YuanGong
{
//定义构造方法
public Manager(){}
public Manager(String name,int age,int money){
super(name,age,money);
}
//重写父类继承过来的work方法
public void work() {
//System.out.println("上班打卡");
super.work();
System.out.println("处理客户矛盾");
}
}
class Cook extends YuanGong
{
//定义构造方法
public Cook(){}
public Cook(String name,int age,int money){
super(name,age,money);
}
//重写父类继承过来的work方法
public void work() {
//System.out.println("上班打卡");
super.work();
System.out.println("炒菜");
}
}
(7)多态(polymorphism)
定义:某一种事物的多种形态。
例:
猫类继承动物类。则猫具有两种形态,即动物与猫。
式子A定义变量普通赋值:猫 a = new 猫();
式子B定义变量多态赋值:动物 b = new 猫();
•分析以上案例,在式子B中,父类的引用指向了子类实例对象。
•多态的程序体现为
父类或者接口的引用指向其子类对象或者实现类对象。
前提:
•需要存在继承或者实现关系。
•要有方法覆盖操作,否则没有意义。
•父类或者接口的引用指向或者接收自己的子类对象。
优点:
•开发当中要符合开闭原则:对修改关闭,对扩展开放。
•多态的存在提高了程序的扩展性和后期可维护性。
特点:
成员函数:
•编译时:要查看引用变量所属的类中是否有所调用的成员函数。
•在运行时:要子类实例中的方法。
成员变量:只看引用变量所属的类。
向上向下转型:
•向上转型:引用变量为父类时,子类实例对象可以自动提升为父类类型
•向下转型:可以使用强制类型转换,完成向下转型
多态的表现形式
•具体类多态
•抽象类多态
•接口多态
抽象类:
抽象定义:
•抽象就是从多个事物中将共性的,本质的内容抽取出来。
•例如:狼和狗共性都是犬科,犬科就是抽象出来的概念。
抽象类定义:
•包含抽象方法的类就是抽象类。
•抽象类不一定包含抽象方法。
•类/抽象类不一定包含方法。
•抽象类可以有非抽象方法。
抽象方法定义:
•多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取 功能主体,那么
只有功能声明,没有功能主体的方法称为
抽象方法。
•例如:狼和狗都有吼叫的方法,可是吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是并不明 确吼叫的细节。
格式:
•抽象类与抽象方法均需要使用abstract关键字。
•抽象方法格式:
修饰符 abstract返回值类型 函数名(参数列表) ;
•抽象类格式:
修饰符 abstract class类名{}
特点:
•抽象类本身无法实例化。
•抽象类通过多态的形式创建其子类实例对象。
•子类需要将抽象父类的抽象方法均覆盖才可以实例化,否则依然是抽象类。
•抽象类强制子类必须实现抽象方法。
注意事项
•抽象类包含构造方法,用来给属性赋值供子类实例对象使用。
•abstract不能与如下关键字公用
-final :抽象类需要继承,final修饰的无法继承
-static :抽象类抽象方法无方法体,调用无意义
-private:抽象类的方法需要被覆盖,如果private修饰的话,子类无法访问
抽象类练习:
/*
老师示例
具体事物:基础班老师,就业班老师
共性:姓名,年龄,讲课。
共三个类:
抽象父类:老师
具体子类:基础班老师
具体子类:就业班老师
父类中成员:
姓名
年龄
public abstract void 讲课();
*/
class Test2
{
public static void main(String[] args)
{
JiChuTeacher jct = new JiChuTeacher("吴尊",32);
jct.teach();
Teacher teacher = new JiChuTeacher("汪东城",34);
teacher.teach();
}
}
//定义抽象父类
abstract class Teacher
{
String name;
int age;
public Teacher(){}
public Teacher(String name,int age) {
this.name = name;
this.age = age;
}
public abstract void teach();
}
//定义具体子类
class JiChuTeacher extends Teacher
{
public JiChuTeacher(){}
public JiChuTeacher(String name,int age) {
super(name,age);
}
public void teach() {
System.out.println("基础班老师"+name+"在教JavaSE!");
}
}
class JiuYeTeacher extends Teacher
{
public JiuYeTeacher(){}
public JiuYeTeacher(String name,int age) {
super(name,age);
}
public void teach() {
System.out.println("JavaEE&Android!");
}
}
概念:比抽象类更为抽象的表现形式
格式:
•定义接口:interfaceXX {}
•使用接口:classYY implements XX{}
特点
•接口是对外暴露的规则。
•接口是程序的功能扩展。
•接口的出现降低耦合性。
•java支持类同时实现多个接口。
•java支持类在继承一个类的同时,实现多个接口。
•接口与接口之间可以有继承关系。并且可以多继承。
•接口不能被实例化。
•接口是”like a”的关系。
接口成员特点:
•接口内的成员修饰符是固定的
-成员常量:public static final,接口中只有常量
-成员函数:public abstract,接口中只有抽象方法
-构造方法:无
接口与抽象类的异同
•均为抽取出的相同概念的抽象。
•类为单继承,接口为多实现。
•继承为”isa”的关系,接口为“like a”的关系。
•抽象类中可以定义非抽象方法,供子类直接使用。接口均为抽象方法,因为固定修饰符。
接口设计练习:
/*
接口设计练习
练习:根据需求设计类与接口
乒乓球运动员和教练
篮球运动员和教练
与乒乓球有关的人员出国考察,要学习英语
分析:
通过题目要求,可以推断出,最少可以为6个类
教练
乒乓球
篮球
运动员
乒乓球
篮球
*/
class Test
{
public static void main(String[] args)
{
PPTeacher ppt = new PPTeacher();
ppt.teach();
ppt.speaking();
PPSporter pps = new PPSporter();
pps.play();
pps.speaking();
BBTeacher bbt = new BBTeacher();
bbt.teach();
//bbt.speaking();
BBSporter bbs = new BBSporter();
bbs.play();
//bbs.speaking();
cn.itcast.Demo01_package dp = new cn.itcast.Demo01_package();
}
}
/*定义一个学习英语的接口*/
interface LearnEn
{
public abstract void speaking();
}
/*定义了一个抽象教练类*/
abstract class Teacher {
public abstract void teach();
}
/*定义了一个抽象运动员类*/
abstract class Sporter {
public abstract void play();
}
//定义具体子类
//乒乓球教练
class PPTeacher extends Teacher implements LearnEn
{
public void teach() {
System.out.println("教乒乓球");
}
public void speaking() {
System.out.println("abc");
}
}
//乒乓球运动员
class PPSporter extends Sporter implements LearnEn
{
public void play() {
System.out.println("练习乒乓球");
}
public void speaking() {
System.out.println("abc");
}
}
//篮球教练
class BBTeacher extends Teacher
{
public void teach() {
System.out.println("教篮球");
}
}
//篮球运动员
class BBSporter extends Sporter
{
public void play() {
System.out.println("练习篮球");
}
}
(8)static
定义:静态修饰符,用于修饰成员(变量与函数)。
修饰后成员特点:
•被所有对象共享
•随着类的加载而加载,与创建对象时机无关
•可以直接通过类名访问或调用
注意事项:
•静态修饰的变量一旦赋值便影响所有实例
•静态方法只能访问静态成员
•静态方法中无法使用this或者super
•主函数是静态的
-static为固定修饰,与对象无关是JVM的入口
-public公共访问权限允许外界调用
-无返回值,定义返回值类型没有意义
-参数为String数组类型,用来接收字符串参数
-函数名为JVM固定查找的字符串不能修改
-形参名可以修改并使用
(9)代码块
定义:一块独立的代码区域,使用{}划定
分类:
•局部代码块
-位置:存在于方法中
-作用:控制变量作用域,影响变量生命周期
•构造代码块
-位置:存在于类中
-作用:将构造器中相同代码抽取,在构造器前执行
•静态构造代码块
-位置:存在与类中
-作用:只在第一次创建对象时初始化一次
•执行顺序:静态构造代码块>构造代码块>局部代码块
注意事项:
•考虑到创建对象的步骤,加入代码块后的顺序为:
静态代码块>默认初始化>显式初始化>构造代码块初始化>构造函数初始化
(10)finall
定义:最终修饰符,修饰类与类的成员。
作用:
•修饰类,类不可以被继承。
•修饰方法,方法不可以被重写。
•修饰变量,变量的值不能更改,成为了常量。
-常量必须有值。
-常量的值只能赋值一次。
-引用类型常量可以更改其堆内存对象中的值。
•内部类只能访问被外部类中被final修饰的局部变量。
(11)包
概念:
•包是用来分类管理类文件的。
•包相当于文件夹,类相当于文件。
•是封装的一种表现形式。
作用:
•为类分类。
•提供多层命名空间。
•类名的全限定名是包括其所属包的。
包的定义:
•定义包时写在程序文件的第一行。
•通常使用公司的域名反写。
•格式:package一级包名.二级包名…;
同包访问:直接访问
跨包访问
•使用全限定名。
•除lang包外,其他包下类的使用均可导包后直接使用。
-同一文件中可以导入多个包。
-import关键字用来导包。
-格式:import mypack.Demo;/import mypack.*;
•被导入的类需要使用public修饰。
•通常一个文件中只定义一个类,而这个类就是使用public修饰的。
•如果一个文件中定义多个类,则只有一个类可以使用public修饰,且这个类的类名需要与文件名相同。
包的访问权限:
概念:内部类又叫内置类或者嵌套类。即在类中定义的另外一个类。是一个相对概念。
内部类是符合面向对象的。如人与心脏的关系。
内部类在编译时,让会生成两个class文件。
访问特点:
•内部类可以直接访问外部类中的成员,包括私有成员。
•而外部类要访问内部类中的成员必须要建立内部类的对象。
分类:
•成员内部类
•局部内部类,匿名内部类属于局部内部类
成员内部类:内部类定义在成员位置。
•访问格式:
-Outer.Inner x = new Outer().new Inner();
-或外部类中方法中,直接创建内部类对象调用其方法。
•可以被private成员修饰符修饰,保证数据安全。
•可以被static成员修饰符修饰,方便调用。
•被static修饰的内部类只能访问外部类中的静态成员。
•static修饰后的访问格式:
-Outer.Inner x = new Outer.Inner();
•调用静态内部类中的静态方法:
-Outer.Inner.method();
局部内部类:内部类定义在方法内。
•无法使用Outer.Inner进行访问。
•访问格式:在所在方法内创建对象进行方法调用
•同时可以访问所在局部中的局部变量,但必须是被final修饰的。
•必须先定义再使用。
匿名内部类概念:
•在通过简写形式定义一个没有类名的类。
•在创建一个对象。
•匿名内部类即将匿名定义类与创建对象的动作一起完成。
•匿名内部类属于局部内部类。
•定义格式:
-匿名内部类需要先定义再使用。
-匿名内部类是一种多态的表现形式。
-new 类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)};
•使用场景:
-1、内部类效率更高。
-2、通常在使用接口类型参数的方法上,并该接口中的方法不超过三个时,可以将匿名内部类作为参数传递。
-3、增强阅读性。
内部类练习:
interface Inter{void show()}
class Outer{//补齐代码}
class innerClassTest{
public static void main(String[] args){
Outer.method.show();
}
}
分析:由于Outer可以直接调用method,说明method 为静态成员变量,又因为method可以调用show(),说明method为接口Inter 的子类对象,即:public static Inter method = new Inter(){void show(){System.out.println("大家好!")}};