Java基础学习——复习 第四天--面向对象编程

6、面向对象编程

6.1面向对象编程基础

    (1)面向对象概述

            1.对象:在现实社会中随处可见的一种食物都是对象,对象是食物存在的实体。通常将对象分为动态和静态两种。静态即属性,动态即行为。

            2.类:类就是同一类事物的统称。

            3.面向对象程序设计的特点

                3.1封装--封装是面向对象编程的核心思想。将对象的属性和行为封装起来,其载体为类,类通常对对象隐藏其实现细节,这就是封装思想。采用封装思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,之恩能够执行类允许公开的数据,这样避免了外部操作对内部数据的影响,提高了程序的可维护性。

                3.2继承--类与类之间的关系,继承是其一种,继承主要是利用特定对象之间的共有属性

                3.3多态--将父类对象应用于子类的特征就是多态。

        (2)类与对象

                1.成员变量--在java中对象的属性也称为成员变量,成员变量的定义与普通变量的定义一样。语法 数据类型 变量名[= 值]   其中[= 值]是可选内容,定义变量时可以为其赋值也可以不赋值。

                2.成员方法--在java中,成员方法对应于类对象的行为,它主要用来定义类可执行的操作,他是包含一系列语句的代码块。

                    2.1成员方法的定义--语法:[权限修饰符][返回值类型]方法名([参数类型 参数名])[throws 异常类型]{

                                                                 …//方法体

                                                                 return 返回值;

                                                                 }

                    2.2成员方法的参数--调用方法时可以给该方法传递一个或多个值,传给内部方法叫实参,在方法内部接受实参的变量叫形参,形参的声明语法与变量的声明语法一样,形参只在方法内部有效

                        2.2.1值参数--表明实参和形参之间按值传递,当值参数被调用时编译器为形参分配存储单元,然后将对应的实参的值复制到形参中,由于是值类型的传递方式,所以在方法中对值类型的形参的修改不会影响到实参。

                        2.2.2引用参数--如果在给方法传递参数时,参数的类型是数组或其他的引用类型,那么在方法中对参数的修改会反映到原有的数组或其他引用类型上,这种类型的参数称之为引用参数。

                        2.2.3不定长参数--声明方法时,如果有若干个相同类型的参数,可以定义为不定长参数,

方法:权限修饰符 返回值类型 方法名(参数类型 …参数名)

                   2.3成员方法的使用

代码实现:

 public class Leopard {

       public voidgaze(String target) {// 凝视。目标是参数target

              System.out.println("猎豹凝视:"+ target);

       }

 

       public voidrun() {// 奔跑

              System.out.println("猎豹开始奔跑");

       }

 

       public booleancatchPrey(String prey) {// 捕捉猎物,返回捕捉是否成功

              System.out.println("猎豹开始捕捉"+ prey);

              returntrue;// 返回成功

       }

 

       public voideat(String meat) {// 吃肉,参数是肉

              System.out.println("猎豹吃"+ meat);

       }

 

       public voidsleep() {// 睡觉

              System.out.println("猎豹睡觉");

       }

 

       public staticvoid main(String[] args) {

              Leopard liebao= new Leopard();

              liebao.gaze("羚羊");

              liebao.run();

              liebao.catchPrey("羚羊");

              liebao.eat("羚羊肉");

              liebao.sleep();

       }

}

结果:

猎豹凝视:羚羊
猎豹开始奔跑
猎豹开始捕捉羚羊
猎豹吃羚羊肉

猎豹睡觉

                3.构造方法--构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。

构造方法的特点:(1)构造方法没有返回类型,也不能定义为void(2)构造方法的名称要与本类的名称相同(3)构造方法的主要作用就是完成对象的初始化工作,他能把定义对象的参数传递给对象成员。

                4.局部变量--在成员方法中定义一个变量,那么这个变量就称为局部变量,局部变量在方法中被执行时创建,方法结束时销毁。

                5.局部变量的有效范围--局部变量的有效范围从该变量的声明开始到该变量的结束为止。

                6.对象的创建--在java语言中使用new创建对象。语法 Test test =new Test();

                7.访问对象的属性和行为--用户使用new操作符创建一个对象后,可以使用“对象.类成员”来获取对象的属性和行为。当对象获取类成员时,也相应的获取了对象的属性和行为

                8.对象的销毁--java会对一下两种情况的对象进行销毁(1)对象引用超过其作用范围,(2)讲对象赋值为null。

                9.this关键字--明确引用的是类成员还是局部变量或者方法参数等。

        (3)static 关键字--由static 修饰的变量、常量和方法被称作静态变量、静态方法、静态常量。

                1.静态变量--java程序中把共享的变量用static修饰,该变量就是静态变量。

                2.静态常量--在java中用 final static 修饰一个成员变量,这个成员变量就是一个静态常量。

                3.静态方法--java中用static修饰的方法就是静态方法。

                4.静态代码块--用static修饰的代码区域为静态代码块。

         (4)类的主方法--主方法是类的入口点,他定义了程序从何处开始;主方法提供对程序控制流向的控制;

主方法的语法:public static void main(String [] args){

//方法体

}

6.2面向对象核心技术

        (1)类的封装

代码实现:

public classRestaurant4 {

        privateCook2 cook = new Cook2();// 餐厅封装的厨师类

 

        publicvoid takeOrder(String dish) {// 下单

                 cook.cooking(dish);//通知厨师做菜

                 System.out.println("您的菜好了,请慢用。");

        }

 

        publicString saySorry() {// 拒绝顾客请求

                 return"抱歉,餐厅不提供此项服务。";

        }

 

        publicstatic void main(String[] args) {

                 Restaurant4water = new Restaurant4();// 创建餐厅对象,为顾客提供服务

                 System.out.println("**请让厨师为我做一份香辣肉丝。***");

                 water.takeOrder("香辣肉丝");//服务员给顾客下单

                 System.out.println("**你们的厨师叫什么名字?***");

                 System.out.println(water.saySorry());//服务员给顾客善意的答复

                 System.out.println("**请让厨师给我切一点葱花。***");

                 System.out.println(water.saySorry());///服务员给善意的答复顾客

        }

}

结果

**请让厨师为我做一份香辣肉丝。***
Tom Cruise洗蔬菜
Tom Cruise切葱花
Tom Cruise开始烹饪香辣肉丝
您的菜好了,请慢用。
**你们的厨师叫什么名字?***
抱歉,餐厅不提供此项服务。
**请让厨师给我切一点葱花。***

抱歉,餐厅不提供此项服务。

封装的思想就是对客户隐藏其细节,

        (2)类的继承--及城市程序开发中重要的概念,使整个程序架构具备一定的弹性,减少开发周期,提高软件的可维护型和可扩展性。

                1.extends关键字--java中让一个类继承另一个类,用extends关键字,语法:子类 extends 父类

                2.方法的重写

                    2.1重写的实现--重写就是在子类中将父类的成员方法的名称保留,重新编写成员方法的实现内容,更改成员方法的存储权限,或是修改成员方法的返回值类型。在继承中还有一种特殊的重写方式,子类与父类的成员方法返回值,方法名称、参数类型及个数完全相同,唯一不同的世方法实现内容,这种特殊的重写方法叫重构。

                    2.2super关键字--用来在方法重写后调用父类的属性和方法。

                3.所有类的父类——Object类--所有类都直接或间接的继承了java.lang.Object类,下面介绍几个重要方法

                    3.1getClass()方法--他会返回对象执行时的class实例,然后使用此实例调用getName方法获取类的名称

                    3.2toString()方法--将一个对象返回为字符串形式,会返回一个String实例

                    3.3equals()方法--比较的是两个对象的实际内容

        (3)类的多态

                1.方法的重载--在同一个类中允许同时存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可。

代码实现:

public classOverLoadTest {

        //定义一个方法

        publicstatic int add(int a) {

                 returna;

        }

        //定义与第一个方法参数个数不同的方法

        publicstatic int add(int a, int b) {

                 returna + b;

        }

        //定义与第一个方法相同名称、参数类型不同的方法

        publicstatic double add(double a, double b) {

                 returna + b;

        }

        //定义一个成员方法

        publicstatic int add(int a, double b) {

                 return(int) (a + b);

        }

        //这个方法与前一个方法参数次序不同

        publicstatic int add(double a, int b) {

                 return(int) (a + b);

        }

        //定义不定长参数

        publicstatic int add(int... a) {

                 ints = 0;

                 //根据参数个数循环操作

                 for(int i = 0; i < a.length; i++) {

                         s+= a[i];// 将每个参数的值相加

                 }

                 returns;// 将计算结果返回

        }

        publicstatic void main(String args[]) {

                 System.out.println("调用add(int)方法:" + add(1));

                 System.out.println("调用add(int,int)方法:" + add(1,2));

                 System.out.println("调用add(double,double)方法:" + add(2.1,3.3));

                 System.out.println("调用add(int a,double b)方法:" + add(1, 3.3));

                 System.out.println("调用add(doublea, int b) 方法:" + add(2.1, 3));

                 System.out.println("调用add(int...a)不定长参数方法:"+ add(1, 2, 3, 4, 5, 6, 7, 8, 9));

                 System.out.println("调用add(int...a)不定长参数方法:" + add(2, 3, 4));

        }

}

结果:

调用add(int)方法:1
调用add(int,int)方法:3
调用add(double,double)方法:5.4
调用add(int a, double b)方法:4
调用add(double a, int b) 方法:5
调用add(int... a)不定长参数方法:45
调用add(int... a)不定长参数方法:9

                2.向上转型--将具体类转换为抽象类

代码实现

classQuadrangle {                                            //四边形类

        publicstatic void draw(Quadrangle q) {//四边形类中方法

                 //SomeSentence

        }

}

 

public classParallelogram extends Quadrangle {

        publicstatic void main(String args[]) {

                 Parallelogramp=new Parallelogram();

                 draw(p);

        }

}


                3.向下转型--将抽象类转化为具体类

代码

classQuadrangle {

        publicstatic void draw(Quadrangle q) {

                 //SomeSentence

        }

}

 

public classParallelogram extends Quadrangle {

        publicstatic void main(String args[]) {

                 draw(newParallelogram());

                 //将平行四边形类对象看作是四边形对象,称为向上转型操作

                 Quadrangleq = new Parallelogram();

                 Parallelogramp = (Parallelogram) q; // 将父类对象赋予子类对象

                

                 将父类对象赋予子类对象,并强制转换为子类型

                 //Parallelogramp = (Parallelogram) q;

        }

}

                4.instanceof关键字--判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类

代码实现

class Quadrangle {

        publicstatic void draw(Quadrangle q) {

                 //SomeSentence

        }

}

 

class Square extends Quadrangle {

        //SomeSentence

}

 

class Anything {

        //SomeSentence

}

 

public class Parallelogram extendsQuadrangle {

        publicstatic void main(String args[]) {

                 Quadrangleq = new Quadrangle(); // 实例化父类对象

                 //判断父类对象是否为Parallelogram子类的一个实例

                 if(q instanceof Parallelogram) {

                         Parallelogramp = (Parallelogram) q; // 进行向下转型操作

                 }

                 //判断父类对象是否为Parallelogram子类的一个实例

                 if(q instanceof Square) {

                         Squares = (Square) q; // 进行向下转型操作

                 }

                 //由于q对象不为Anything类的对象,所以这条语句是错误的

                 //System.out.println(q instanceof Anything);

        }

}


        (4)抽象类与接口

                1.抽象类与抽象方法--定义抽象类时,需要使用abstract关键字

代码实现:

public abstract class Market {

        publicString name;//商场名称

   public String goods;//商品名称

   public abstract void shop();//抽象方法,用来输出信息

}

public classTaobaoMarket extends Market {

    @Override

        publicvoid shop() {

                 //TODO Auto-generated method stub

                 System.out.println(name+"网购"+goods);

        }

}

public classWallMarket extends Market {

        @Override

        publicvoid shop() {

                 //TODO Auto-generated method stub

                 System.out.println(name+"实体店购买"+goods);

        }

 

}

/**

 * 使用抽象类模拟“去商场买衣服”的案例,然后通过派生类确定到底去哪个商场买衣服,买什么样的衣服。

 */

public classGoShopping {

        publicstatic void main(String[] args) {

                 Marketmarket = new WallMarket();// 使用派生类对象创建抽象类对象

                 market.name= "沃尔玛";

                 market.goods= "七匹狼西服";

                 market.shop();

                 market= new TaobaoMarket();// 使用派生类对象创建抽象类对象

                 market.name= "淘宝";

                 market.goods= "韩都衣舍花裙";

                 market.shop();

        }

}

结果:

沃尔玛实体店购买七匹狼西服

淘宝网购韩都衣舍花裙

使用抽象类和抽象方法时,需要遵循以下原则

1)在抽象类中,可以包含抽象方法,也可以不包含抽象方法,但是包含了抽象方法的类必须被定义为抽象类

2)抽象类不能直接实例化,即使抽象类中没有声明抽象方法,也不能实例化

3)抽象类被继承后,子类需要实现其中所有的抽象方法

4)如果继承抽象类的子类也被声明为抽象类,则可以不用实现父类中所有的抽象方法

                2.接口的声明及实现--接口是抽象类的延伸,接口中所有方法都没有方法体

代码实现:

interfacedrawTest { // 定义接口

        publicvoid draw(); // 定义方法

}

 

// 定义平行四边形类,该类实现了drawTest接口

classParallelogramgleUseInterface implements drawTest {

        publicvoid draw() { // 由于该类实现了接口,所以需要覆盖draw()方法

                 System.out.println("平行四边形.draw()");

        }

}

 

// 定义正方形类,该类实现了drawTest接口

classSquareUseInterface implements drawTest {

        publicvoid draw() {

                 System.out.println("正方形.draw()");

        }

}

 

public classQuadrangleUseInterface { // 定义四边形类

        publicstatic void main(String[] args) {

                 drawTest[]d = { // 接口也可以进行向上转型操作

                                  newSquareUseInterface(), new ParallelogramgleUseInterface() };

                 for(int i = 0; i < d.length; i++) {

                         d[i].draw();// 调用draw()方法

                 }

        }

}

结果

正方形.draw()
平行四边形.draw()

                3.多重继承--java中实现多重继承,须使用接口

代码实现:

public interfaceIFather {// 定义一个接口

        voidsmoking();// 抽烟的方法

 

        voidgoFishing();// 钓鱼的方法

}

public interfaceIMather {// 定义一个接口

        voidwatchTV();// 看电视的方法

 

        voidcooking();// 做饭的方法

}

public classMe implements IFather, IMather {// 继承IFather接口和IMather接口

 

        @Override

        publicvoid watchTV() {// 重写watchTV()方法

                 System.out.println("我喜欢看电视");

        }

 

        @Override

        publicvoid cooking() {// 重写cook()方法

                 System.out.println("我喜欢做饭");

        }

 

        @Override

        publicvoid smoking() {// 重写smoke()方法

                 System.out.println("我喜欢抽烟");

        }

 

        @Override

        publicvoid goFishing() {// 重写goFishing()方法

                 System.out.println("我喜欢钓鱼");

        }

 

        publicstatic void main(String[] args) {

                 IFatherfather = new Me();// 通过子类创建IFather接口对象

                 System.out.println("爸爸的爱好:");

                 //使用接口对象调用子类中实现的方法

                 father.smoking();

                 father.goFishing();

                 IMathermather = new Me();// 通过子类创建IMather接口对象

                 System.out.println("\n妈妈的爱好:");

                 //使用接口对象调用子类中实现的方法

                 mather.cooking();

                 mather.watchTV();

        }

}

结果:

爸爸的爱好:
我喜欢抽烟
我喜欢钓鱼


妈妈的爱好:
我喜欢做饭
我喜欢看电视

                4.区分抽象类与接口--抽象类是对根源的抽象,接口是对动作的抽象

抽象类与接口的不同

比较项

抽象类

接口

方法

可以有非抽象类

所有方法都是抽象方法

属性

属性中可以有非静态常量

所有的属性都是静态常量

构造方法

有构造方法

没有构造方法

继承

一个类只能继承一个父类

一个类可以同时实现多个接口

被继承

一个类只能继承一个父类

一个接口可以同时继承多个接口

 


        (5)访问控制

                1.访问控制符

Java语言中的访问控制符权限

 

Public

Protected

Default(缺省)

Private

本类

可见

可见

可见

可见

本类所在包

可见

可见

可见

不可见

其他包中的子类

可见

可见

不可见

不可见

其他包中的非子类

可见

不可见

不可见

不可见

 使用访问控制符时,需要遵循以下原则:

1)大部分顶级类都是用public修饰;

2)如果某个类主要用作其他类的父类,该类中包含的大部分方法只是希望被其子类重写,要不想被外界直接调用,则应该使用protected修饰;

3)类中的绝大部分属性都应该使用private修饰,除非一些static或者类似全局变量的属性,才考虑使用public修饰;

4)当定义的方法只是用于辅助实现该类的其他方法(即工具方法),应该使用private修饰;

5)希望允许其他类自由调用的方法应该使用public修饰。

                2.java类包--类包不仅可以解决类名冲突问题,还可以在开发庞大的应用程序是,帮助开发者管理庞大的应用程序组件,方便软件复用

                3.final关键字

                    3.1final类--定义为final不能被继承。

                    3.2final方法--final方法不能被重写,可以防止子类修改该类的定义与实现方式,同时定义final的方法执行效率远高于非final方法。

                    3.3final变量--用于变量声明,一旦该变量被设定,就不可以在改变该变量的值。

        (6)内部类

                1.成员内部类

                    1.1成员内部类的简介--在一个类中使用内部类,可以直接存取其所在类的私有成员变量。

语法:public class OuterClass{//外部类

        private class InnerClass{//内部类

            //……

}

}

                    1.2内部类向上转型为接口

代码实现:

interfaceOutInterface { // 定义一个接口

        publicvoid f();

}

 

public classInterfaceInner {

        publicstatic void main(String args[]) {

                 OuterClass2  out = new OuterClass2 (); // 实例化一个OuterClass2对象

                 //调用doit()方法,返回一个OutInterface接口

                 OutInterfaceoutinter = out.doit();

                 outinter.f();// 调用f()方法

        }

}

 

classOuterClass2  {

        //定义一个内部类实现OutInterface接口

        privateclass InnerClass implements OutInterface {

                 InnerClass(Strings) { // 内部类构造方法

                         System.out.println(s);

                 }

 

                 publicvoid f() { // 实现接口中的f()方法

                         System.out.println("访问内部类中的f()方法");

                 }

        }

 

        publicOutInterface doit() { // 定义一个方法,返回值类型为OutInterface接口

                 returnnew InnerClass("访问内部类构造方法");

        }

}

                    1.3使用this关键字获取内部类与外部类的引用--在外部类与内部类的成员变量名称相同时可以使用this关键字

                2.局部内部类--可以在类的局部位置进行定义。

代码实现:

interface OutInterface2 { // 定义一个接口

}

class OuterClass3 {

        publicOutInterface2 doit(final String x) { // doit()方法参数为final类型

                 //在doit()方法中定义一个内部类

                 classInnerClass2 implements OutInterface2 {

                         InnerClass2(Strings) {

                                  s= x;

                                  System.out.println(s);

                         }

                 }

                 returnnew InnerClass2("doit");

        }

}

内部类被定义在了doit()方法内部。在doit()方法外部无法访问该内部类,但该内部类可以访问当前代码块的常量以及此外部类的所有成员

                3.匿名内部类

代码实现

interfaceOutInterface2 { // 定义一个接口

}

 

classOuterClass4 {

        publicOutInterface2 doit() { // 定义doit()方法

                 returnnew OutInterface2() { // 声明匿名内部类

                         privateint i = 0;

 

                         publicint getValue() {

                                  returni;

                         }

                 };

        }

}

使用匿名内部类应该遵循以下原则:

1)匿名类没有构造方法

2)匿名类不能定义静态的成员

3)匿名类不能用private、public、protected、static、final、abstract等修饰符

4)只可以创建一个匿名类实例。

                4.静态内部类--在内部类前加static修饰,该内部类就是静态内部类(在程序开发中比较少见)

                5.内部类的继承--需要设置专门的语法来完成

代码实现

public classOutputInnerClass extends ClassA.ClassB { // 继承内部类ClassB

        publicOutputInnerClass(ClassA a) {

                 a.super();

        }

}

 

class ClassA{

        classClassB {

        }

}

在某个类继承内部类时,必须硬性的给予这个类一个带参数的构造方法,并且该构造方法的参数必须是该内部类的外部类引用,就像例子中的ClassA  a,同时在构造方法体重使用a.super()语句


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值