黑马程序员_JAVA之面向对象

来源:互联网 发布:记忆宫殿知乎 编辑:程序博客网 时间:2024/06/05 10:33

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

面向对象

一、基本概述

定义:面向对象(Object Oriented,OO)是软件开过过程中使用一种思维方式 。

面向过程:强调功能行为,关注完成的过程;

面向对象:将功能封装进对象,强调具备了功能的对象,不关注过程;

面向对象与面向过程都是一种思想,面向对象是基于面向过程的。

面向对象的特点:

是一种更符合人们思考习惯的思想。

可以将复杂的事情简单化。

将程序由执行者转换成了指挥者。


面向对象完成需求:

明确开发功能需求。
查找具有该功能的类。
如果不存在满足功能的类,则定义这样的类。
创建该类对象,使用对象完成功能。


面向对象的三大特征:

封装(encapsulation)

继承(inheritance)

多态(polymorphism)


类与对象概述

类定义:具有相同特征(属性)和行为(功能)的一类事物的抽象。

比如:人类有身高,体重等属性,有说话,打球等行为。

动物类有年龄,性别等属性,有吃饭,睡觉等行为。

对象定义:类的实体

比如:人类是类的定义,张三李四便是人类的实体对象。

水果类是类的定义,苹果橘子是水果类的实体对象。

类与对象的关系:

类是抽象概念,对象是类的具体实例。

一个类可以有多个对象。一个对象只属于一个类。

对象创建格式:

数据类型 变量名(对象名) = new 数据类型(参数);

对象的使用:

成员变量的访问:

对象名.属性名

成员函数的调用:

对象名.函数名(参数)

举例:Phone类

代码实现:

/*手机事物:属性:品牌(brand) , 颜色(color) , 价格(price) .... 行为:打电话(call) , 发短信(sendMessage) , 玩游戏(playGame) ...手机类:成员变量: 品牌(brand) , 颜色(color) , 价格(price) 成员方法: 打电话(call) , 发短信(sendMessage) , 玩游戏(playGame)*/class Phone {// 成员变量// 品牌String brand = "三星";// 颜色String color = "白色";//  价格int   price = 998 ;// 成员方法// 打电话public void call(String name){System.out.println("给" + name + "打电话");}// 发短信public void sendMessage(String name){System.out.println("给" + name + "发短信");}// 玩游戏public void playGame(){System.out.println("玩游戏....");}}

类的使用代码实现

// 手机类class Phone {// 成员变量String brand ;// 品牌String color ;// 颜色int    price ;// 价格// 成员方法// 打电话public void call(String name){System.out.println("给" + name + "打电话");}// 发短信public void sendMessage(String name){System.out.println("给" + name + "发短信");}// 玩游戏public void playGame(){System.out.println("玩游戏....");}}// 测试类class PhoneDemo {public static void main(String[] args){// 创建手机对象Phone p = new Phone();// 输出所有的成员变量System.out.println(p.brand + "---" + p.color + "----" + p.price);// 给成员变量赋值p.brand = "诺基亚";p.color = "黑色";p.price = 199 ;// 输出所有的成员变量System.out.println(p.brand + "---" + p.color + "----" + p.price);// 调用方法p.call("刘亦菲");p.sendMessage("刘亦菲");p.playGame();}}

成员变量与局部变量概述

成员变量:

定义位置:类中,整个类中均可以访问。
内存:成员变量随着对象的建立而建立,存在于对象所在的堆内存中。
默认值:成员变量有默认值。

回收:随着对象的回收而回收。

局部变量:

定义位置:定义域局部范围,如函数内,语句内等。
内存:局部变量存在于栈内存中。
默认值:没有默认值。
回收:随着作用域结束而回收,通常为语句或函数范围。

变量访问原则:就近原则

代码实现:

class Demo {int b ;int a = 40 ;public void show(){// 错误的: 可能尚未初始化变量a// int a ;// System.out.println(a);int a = 30 ;System.out.println(a);}}class VariableDemo {public static void main(String[] args){// 创建Demo对象Demo d = new Demo();// 调用show方法d.show();// 获取bSystem.out.println(d.b);}}

三大特征之封装

概述:

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

优点:

将变化隔离

便于使用

提高重用性

提高安全性

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

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

private关键字:

是一个权限修饰符。

用于修饰成员(成员变量和成员函数)

被私有化的成员只在本类中有效。

常用方式:将成员变量私有化,对外提供对应的set ,get方法对其进行访问。提高对数据访问的安全性。

this关键字:

定义:this代表其所属对象的引用。没有实例对象,this就没有意义。

使用:

当在函数内需要用到调用该函数的对象时,就用this

局部变量隐藏成员变量时,使用this区分。

构造函数中第一行,用来调用本类其他重载的构造函数。

代码实现:封装学生类

// 学生类class Student {// 定义成员变量private String name ;// 姓名private int   age ;// 年龄private String sex ;// 性别// 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 setSex(String sex){this.sex = sex ;}public String getSex(){return sex ;}}// 测试类class StudentDemo {public static void main(String[] args){// 创建学生对象Student s = new Student() ;// 给成员变量赋值s.setName("小花");s.setAge(18);s.setSex("女");// 输出成员变量System.out.println(s.getName() + "----" + s.getAge() + "----" + s.getSex());}}

三大特征之继承

概述:定义:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

这多个类称为子类,单独这个类称为父类或者超类。子类可以直接访问父类中非私有的成员变量与成员方法。

格式:通过 extends 关键字让类与类之间产生继承关系

class SubDemo extends Demo{}

优点:继承的出现提高了代码的复用性。

继承的出现让类与类之间产生了关系,是多态的前提之一。

弊端:使类与类之间产生了更强的耦合性

代码实现:

class Demo5{public static void main(String[] args){Cat cat = new Cat();cat.eat();Dog dog = new Dog();dog.eat();System.out.println(cat.name);//System.out.println(cat.age);}}class Animal{String name = "四不像";private int age = 20;public void eat(){System.out.println("吃了");}public void sleep(){System.out.println("睡了");}}class Cat extends Animal{public void catchMouse(){System.out.println("猫抓老鼠的方法");}}class Dog extends Animal{}class Person extends Animal{}

特点:

java只支持单继承不支持多继承。

java支持多层继承。

任何类都直接或者间接继承自Object类。

注意事项:

不要为了某个功能而去继承,需要满足”is a”的关系。

代码时下:

class Demo6 {public static void main(String[] args) {Manager m = new Manager();m.eat();System.out.println(m.hashCode());Boss boss = new Boss();boss.eat();boss.keepMoney();}}class Animal{String name = "四不像";private int age = 20;public void eat(){System.out.println("吃了");}public void sleep(){System.out.println("睡了");}}class Cat extends Animal{public void catchMouse(){System.out.println("猫抓老鼠的方法");}}class Dog extends Animal{public void keepMoney() {System.out.println("钱看住了!");}}class Person extends Animal{}class Manager extends Person{}//不同种类的继承是不应该存在,不能为了某个功能而继承不同种类的类。//继承时必须符合"is a"的关系。//如果仅仅是需要里边的某个功能的话,可以时候后边学习的"实现"class Boss extends Dog{}

继承后的成员特点:

成员变量:访问满足就近原则

局部变量>成员变量>父类成员变量>父类的父类

代码实现

class Demo7 {public static void main(String[] args) {Cat cat = new Cat();cat.catchMouse();//System.out.println(cat.name);}}class Animal{String name = "哺乳动物";private int age = 20;public void eat(){System.out.println("吃了");}public void sleep(){System.out.println("睡了");}}class Cat extends Animal{String name = "kitty";public void catchMouse(){String name = "Tom";System.out.println("我是"+name);System.out.println("猫抓老鼠");//super.eat();super.eat();}}class Dog extends Animal{}


成员方法:

子类可以直接使用父类的非私有方法。
当子父类方法一样时,方法重写。

代码实现:

class Demo8 {public static void main(String[] args) {Cat cat = new Cat();cat.eat();//cat.sleep();//cat.catchMouse();}}class Animal{public void eat(){System.out.println("吃了");}public void sleep(){System.out.println("睡了");}}class Cat extends Animal{public void catchMouse(){System.out.println("猫抓老鼠");//super.eat();super.eat();eat();this.eat();}public void eat(){System.out.print("喵,");super.eat();}}


构造方法:

构造方法不继承,子类的构造默认调用父类构造。
父类构造方法负责对成员变量初始化供子类对象使用,而不是创建父类对象。
父类没有无参构造时,子类需要手动调用其他父类构造。

代码实现

class Demo10{public static void main(String[] args) {Cat cat = new Cat("Tom");//Animal a = new Animal();System.out.println(cat.getName());//Cat cat2 = new Cat();//System.out.println(cat2.getName());}}class Animal{private String name = "哺乳动物";public Animal(){System.out.println("我是父类Animal中的空参构造");}public Animal(String name){this.name = name;System.out.println("我是父类Animal中的有一个参数的构造");}public void setName(String name) {this.name = name;}public String getName() {return name;}}class Cat extends Animal{public Cat(){//super();super("庞中华");System.out.println("我是子类Cat中的空参构造");}public Cat(String name){//super();super(name);System.out.println("我是父类Animal中的有一个参数的构造");}}



方法重载与方法重写:

重载:一般是在同一个类中,(但是也有可能在子父类中包含重载关系)

规则:

方法名相同

参数列表不同:类型不同,个数不同,顺序不同

与其他内容都无关

重写:一定涉及两个或两个以上的类,并且有子父类关系

规则:

访问权限:相同 或者 子类访问权限大于父类访问权限

函数名:相同

参数列表:相同

返回值类型:

void符合基本类型的规律

基本数据类型:必须相同

引用数据类型:相同  或者  不同时,父类返回值是子类返回值的父类是可以的。(子类返回值小于父类)

静态方法只能覆盖静态方法

代码实现:

  System.out.println("子类重写的静态方法");

class Demo9{public static void main(String[] args) {Cat cat = new Cat();cat.eat();//cat.eat("fish");cat.sleep();}}//访问权限    默认的<publicclass Animal{public Fu eat(){System.out.println("吃了");return new Fu();}public static void sleep(){System.out.println("父类的静态方法");}/*public void eat(String food){System.out.println("吃了"+food);}*/}class Cat extends Animal{public Zi eat(){System.out.println("喵,吃了");return new Zi();}public static void sleep(){}}class Fu{}class Zi extends Fu{}

this和super关键字

this:

方式一:用来访问父类存储空间的成员

方式二:用来在子类的构造方法中调用父类的构造方法

super:

方式一:用来访问子类自己的成员

方式二:用来在本类的构造方法中调用本类的其他构造方法

this与super调用构造方法都必须放在第一行

子父类构造方法设计原则:至少有一个构造必须先访问父类构造,在父类构造完毕之后,再访问本类构造

代码实现:

class Demo11 {public static void main(String[] args) {Cat cat = new Cat("kitty");//cat.eat();cat.catchMouse();}}class Animal{String name = "哺乳动物";public Animal(){System.out.println("我是父类Animal中的空参构造");}public Animal(String name){this.name = name;System.out.println("我是父类Animal中的有一个参数的构造");}public void eat(){System.out.println("我是父类中的eat方法");}}class Cat extends Animal{//String name = "Tom";int age = 10;public Cat(){//super();System.out.println("我是子类Cat中的空参构造");}public Cat(String name){super(name);System.out.println("我是父类Animal中的有一个参数的构造");}public Cat(int age) {this.age = age;}public Cat(String name,int age) {//super(name);//仅仅给年龄赋值,不管姓名时this(age);}public void eat(){System.out.println("我是子类中的eat方法");}public void catchMouse(){System.out.println("我是子类中的catchMouse方法"+super.name);super.eat();}}

final关键字:最终修饰符

修饰类:类无法被继承

修饰方法:方法无法被重写

修饰变量:

成员变量:

必须被赋值,只能赋值一次。

赋值动作需要在对象创建完成之前执行

局部变量:

只能赋值一次

代码实现:



class Demo {public static void main(String[] args) {Cat cat = new Cat("kitty");//Cat cat = new Cat();//cat.name = "Tom";System.out.println(cat.name);cat.myMethod();cat.myMethod2("石家庄");cat.myMethod3(28);Person p = new Person("段正淳",30);  //0x1234cat.myMethod4(p);}}//final class Animal 被final修饰的类无法被继承class Animal{public final void method(){}}class Cat extends Animal{/*子类无法重写父类中final修饰的方法public void method(){System.out.println("我是子类的方法");}*///final String name = "Tom";final String name;//public Cat(){}  //如果同时还存在空参不给name赋值的构造,则会报错:可能尚未初始化。public Cat(String name){this.name = name;}//定义方法,测试final修饰局部变量public void myMethod(){final String city = "北京";//city = "张家口";  final修饰的变量只能赋值一次System.out.println(city);}public void myMethod2(final String city){//city = "北京";//city = "张家口";  final修饰的变量只能赋值一次System.out.println(city);}public void myMethod3(final int age){//age = 30;System.out.println(age);}public void myMethod4(final Person p){//0x1234p.name = "段延庆";p.age = 40;//p = new Person("段誉",18); //0x2234}}

三大特征之多态

概述:

定义:某一种事物的多种形态。

前提:

必须多态的两个类间存在关系(继承/实现)

要有方法覆盖操作,否则没有意义

java中父类引用指向子类对象

代码实现:



class Demo2 {public static void main(String[] args) {Animal a = new Animal();    //动物是动物Cat c = new Cat();          //猫是猫Animal a2 = new Cat();      //猫是动物//Cat c2 = new Animal();      //动物是猫}}class Animal{}class Cat extends Animal{}

多态的优点及特点:

优点:

开发当中要符合开闭原则:对修改关闭,对扩展开放。

多态的存在提高了程序的扩展性和后期可维护性。

特点(规则):

成员变量:

编译期:看左边  / 看父类

运行期:看左边  / 看父类

成员函数:

编译期:看左边  / 看父类

运行时:看右边  / 看子类

只有在调用方法时,检查子类是否有重写,子类重写调用子类重写的方法,其余所有内容均看父类类型。只有调用方法看子类。

代码实现:

class Demo3{public static void main(String[] args) {//使用多态的方式创建一个Cat对象Animal a = new Cat();   //System.out.println(a.name);a.methodFu();//a.methodZi();}}class Animal{//String name = "花花";public void methodFu(){System.out.println("我是父类中的方法");}}class Cat extends Animal{String name = "曹操";/*多态时,调用父类没有的子类方法不可以public void methodZi(){System.out.println("我是子类中的方法");}*///子类重写父类的方法public void methodFu(){System.out.println("我是子类中重写的父类方法");}}

向上向下转型:

向上转型:引用变量为父类时,子类实例对象可以自动提升为父类类型   子↑父

向下转型:可以使用强制类型转换,完成向下转型                     父↓子

代码实现:

class Demo4{public static void main(String[] args) {//第一次调用Animal a = new Cat();method(a);//第二次调用Cat cat = new Cat();method(cat);//第三次调用Cat cat2 = new Cat();method2(cat2);//使用第四调用的方法演示向下类型转换Cat cat3 = new Cat();method3(cat3);Animal a2 = new Animal();method3(a2);}//第一次调用 Animal a >>  Animal b  >>  Animal c//第二次调用 Cat cat  >>  Animal b  >>  Animal cpublic static void method(Animal b){  Animal c = b;c.methodFu();}//第三次调用 Cat cat  >>  Animal bpublic static void method2(Animal b){  b.methodFu();}//第四次调用 Cat cat  >>  Animal b  >>  Animal c  >> Cat d(此步骤为强转)   这样是可以的   对象原本就是Cat可以强转成Cat//Animal a2  >>  Animal b  >>  Animal c  >> Cat d(此步骤为强转)   这样是不可以的          对象原本不是Cat不能强转成Catpublic static void method3(Animal b){  Animal c = b;//c.methodZi();  父类类型没有methodZi方法Cat d = (Cat)c;d.methodFu();d.methodZi();  //强转成子类对象后,可以调用子类对象自己的方法}}class Animal{String name = "kitty";public void methodFu(){System.out.println("我是父类中的方法");}}class Cat extends Animal{public void methodFu(){System.out.println("我是子类中重写父类的方法");}public void methodZi(){System.out.println("我是子类中的特有方法");}}class Dog extends Animal{public void methodFu(){System.out.println("我是子类中重写父类的方法");}public void methodZi(){System.out.println("我是子类中的特有方法");}}

抽象类:

抽象定义:

抽象就是从多个事物中将共性的,本质的内容抽取出来。

例如:狼和狗共性都是犬科,犬科就是抽象出来的概念。

抽象类定义:

包含抽象方法的类就是抽象类。

抽象类不一定包含抽象方法。

类/抽象类不一定包含方法。

抽象类可以有非抽象方法。

抽象方法定义:

多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。

抽象声明格式:

声明一个方法是抽象的:在方法前加abstract关键字

声明一个类是抽象的:在类前加abstract关键字

代码实现:



class Demo9 {public static void main(String[] args) {System.out.println("Hello World!");}}abstract class Animal{//public abstract void eat();/*public void sleep(){System.out.println("睡");}*/}

抽象类的特点:

抽象类无法实例化

抽象类通过多态的形式创建其子类实例对象

子类需要将抽象父类的抽象方法均覆盖才可以实例化,否则依然是抽象类

抽象类强制子类必须实现抽象方法

代码实现:



class Demo10{public static void main(String[] args) {Animal animal = new Cat();//Animal animal = new BoSiCat();}}abstract class Animal{public abstract void eat();public abstract void sleep();}abstract class Cat extends Animal{/*public void eat() {System.out.println("吃鱼!");}*///public abstract void eat();public void sleep(){System.out.println("睡了");}}class BoSiCat extends Cat{public void eat() {System.out.println("吃鱼!");}}

接口:

比抽象类更抽象的表现形式

抽象类可以有非抽象方法接口中全部必须是抽象方法

格式:

定义接口:interface XX {}

使用接口:class YY implements XX{}  类实现接口

代码实现:

class Demo11 {public static void main(String[] args) {MyInterface mi = new MyClass();mi.method();}}interface MyInterface{public abstract void method();}class MyClass implements MyInterface{public void method() {System.out.println("我是类中重写的接口方法");}}

接口的成员特点:成员变量与成员函数均为固定的修饰符!

构造方法:没有!

public static final XXX  xxx = yyy;  >>定义一个常量

成员变量:public static final

成员方法:public abstract 

代码实现:

class Demo13{public static void main(String[] args) {MyInterface mf = new MyClass();System.out.println(MyInterface.age);}}interface MyInterface{String name = "杨幂";int age = 28;public abstract void method();}class MyClass implements MyInterface{public void method(){System.out.println("abc");}}

内部类

概念:内部类又叫内置类或者嵌套类。即在类中定义的另外一个类。是一个相对概念。

访问特点:

内部类可以直接访问外部类中的成员,包括私有成员。

而外部类要访问内部类中的成员必须要建立内部类的对象。

分类:

成员内部类

局部内部类,匿名内部类属于局部内部类

创建成员内部类对象的格式:

Outer.Inner x = new Outer().new Inner();

记忆方式:对比成员变量与成员函数

访问成员变量:对象.属性

调用成员方法:对象.方法名()

创建成员内部类对象: 对象.new 内部类(参数)

代码实现:

public class Demo11{public static void main(String[] args) {//定义一个内部类引用变量//Outer.Inner x  //创建一个外部类对象//Outer out = new Outer();//通过一个外部类对象创建其内部类对象//out.new Inner();Outer.FieldInner x = new Outer().new FieldInner();x.inMethod();Outer out = new Outer();//访问成员变量String name = out.name;System.out.println(name);//调用成员方法out.method();//创建成员内部类对象Outer.FieldInner inner = out.new FieldInner();//Outer.FieldInner inner = new out.FieldInner();  错误的格式,会将out.误认为包名inner.inMethod();}}class Outer{String name = "梁洛施";//成员内部类class FieldInner{//String name = "梁家辉";public void inMethod(){//String name = "梁朝伟";System.out.println(name);}}public void method(){System.out.println("我是外部类的一个普通方法");}/*public void outMethod(){//局部内部类class MethodInner{}}*/}

局部内部类:内部类定义在方法内。

无法使用Outer.Inner进行访问。

访问格式:在所在方法内创建对象进行方法调用

同时可以访问所在局部中的局部变量,但必须是被final修饰的。

必须先定义再使用。

代码实现:

class Demo14{public static void main(String[] args) {Outer out = new Outer();out.outMethod();}}class Outer{String name = "梁洛施";public void outMethod(){final String name = "梁咏琪";//局部内部类class MethodInner{public void method(){System.out.println("我是局部内部类的方法");System.out.println(name);}}MethodInner mi = new MethodInner();mi.method();}}

匿名内部类:

在通过简写形式定义一个没有类名的类。

在创建一个对象。

匿名内部类即将匿名定义类与创建对象的动作一起完成。

匿名内部类属于局部内部类。

定义格式:

匿名内部类需要先定义再使用。

匿名内部类是一种多态的表现形式。

new 类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)};

使用场景:

1、内部类效率更高。

2、通常在使用接口类型参数的方法上,并该接口中的方法不超过三个时,可以将匿名内部类作为参数传递。

3、增强阅读性。

代码实现:

class Demo16 {public static void main(String[] args) {//以前有名字的类:第一步定义有名字的类    第二步创建对象,使用对象//有名字的对象 有名字的类Fu 对象名 = new 类名();对象名.method();//没名字的匿名对象 有名字的类new 类名().method();System.out.println("===============================================");//有名字的对象  没有名字的类Fu noNameObject = new Fu() {public void method() {System.out.println("我是匿名内部类1重写的父类方法");}};noNameObject.method();//没有名字的对象  没有名字的类new Fu() {public void method() {System.out.println("我是匿名内部类2重写的父类方法");}}.method();}}abstract class Fu{public abstract void method();}class 类名 extends Fu{public void method() {System.out.println("我是子类重写的父类方法");}}


0 0
原创粉丝点击