Java的第七章总结

目录

7.1 类的封装

7.2 类的继承

7.2.1 extends关键字

  7.2.2 方法的重写

1、重写的实现

2、super 关键字

7.3 类的多态 

7.3.1 方法的重载

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

7.3.3 向下转型

7.3.4 instanceof 关键字

7.4.2 接口的声明及实现

7.4.3 多重继承 

7.5.3 final 关键字 

目录

7.1 类的封装

7.2 类的继承

7.2.1 extends关键字

  7.2.2 方法的重写

1、重写的实现

2、super 关键字

7.3 类的多态 

7.3.1 方法的重载

7.3.3 向下转型

7.3.4 instanceof 关键字

7.4.2 接口的声明及实现

7.4.3 多重继承 

7.5.3 final 关键字 

7.6  内部类7.6.1 成员内部类



7.1 类的封装

封装是面向对象编程的核心思想,将对象的属性和行为封装起来,其载体就是类。

例如:创建一个类,实现餐馆点菜的场景

public class  Restaurant1 {
   public static viod main(String[] args) {
       String cookName="Tom Cruise"; //厨师的名字叫Tom Cruise
       System.out.println("**请厨师为我做一份香辣肉丝。***");
       System.out.println(cookName + "加葱花");
       System.out.println(cookName + "洗蔬菜");
       System.out.println(cookName + "开始烹饪" + "香辣肉丝");
       System.out.println( "请问厨师叫什么名字?***");
       System.out.println(cookName)
       System.out.println( "**请厨师给我切一点葱花。***");
       System.out.println(cookName + "切葱花");

 所有的逻辑代码全是在main方法中实现的,代码完全暴露,我可以任意删改。如果能随意修改代码,就无法正常运作。为防止其他人修改厨师行为将厨师单独封装成一个类,将厨师的工作定义成厨师类的行为。

 厨师有些属性和行为是不给予公开的,我们用private来修饰。此时在运行餐厅的主方法就会出现异常,提示Cook2的name和cutOnion()不可以直接调用。

 

 顾客与厨师是完全没有交集的,厨师是对顾客隐藏起来的,被封装在餐馆的类当中。这种编程模式就是封装。

 
public class Restaurant { 
		  	 private Cook2 cook = new Cook2 (); //餐厅封装的厨师类
		   public static void takeOrder (String dish) { //下单
			cook.cooking(dish); //通知厨师做菜
		System.out.println("您的菜好了,请慢用。");		
	}
		   public String saySorry()  {//拒绝客户要求
			   return "抱歉,餐厅不提供此项服务。";
		   }
		   public static void main(String[] args) {
           Restaurant waiter = new  Restaurant();//创建餐厅对象,为顾客提供服务
		   System.out.println("**请厨师为我做一份鱼香肉丝。***");
		   waiter.takeOrder("鱼香肉丝");//服务员给顾客下单
		   System.out.println("**你们厨师叫什么名字?***");
		   System.out.println(waiter.saySorry());//服务员给顾客善意的答复
		   System.out.println("**请厨师给我切一点葱花。***"); 
		   System.out.println(waiter.saySorry());//服务员给顾客善意的答复
	   }
   }

 封装的思想:将对象的属性和行为封装起来的载体就是类,类通常对顾客隐藏其实现细节。

7.2 类的继承


继承在面向对象开发思想中是一个非常重要的概念,它使整个程序框架结构具有一定的弹性,还可以提高软件的可维护性和可扩展性。

基本思想:基于某个父类的扩展,制定出一个新的子类。子类可以继承父类原有的属性和方法,也可以增加原有父类所不具备的属性和方法,或者直接重写父类中的某些方法

7.2.1 extends关键字


让一个类继承另一个类,用extends关键字,语法如下:
child  extends  parents

这里child这个类作为子类继承parents这个类,并继承parents中的属性和方法。

注意:Java中的类只支持单继承,即一个子类只能继承自一个父类。

 

  7.2.2 方法的重写


1、重写的实现

(1)继承并不只是扩展父类的功能,还可以重写父类的方法。

(2)重写(覆盖):在子类中将父类的成员方法的名称保留,重新编写成员方法的实现内容,更改成员方法的储存权限,或是修改成员方法的返回值类型。

(3)特殊的重写方式:子类与父类的成员方法返回值、方法名称、参数类型及个数完全相同,唯一不同的是方法实现内容,这种方式被称为重构。

   注意:当重写父类方法时,修改方法的修饰权限只能从小范围到大的范围改变。

 注意:一个类只可以有一个父类。

2、super 关键字

super关键字的使用方法与this关键字类似

super.property;       //调用父类的属性

super.method();      //调用父类的方法

在继承的机制中,创建一个子类对象,将包含一个父类对象。两者的区别在于后者来自外部,而前者来自子类对象的内部。

7.2.3 所以类的父类——Object类
在Java中,所有的类都直接或间接继承了java.lang.Object类。Object类是比较特殊的类,它是所有类的父类,是Java类的最高层类。

Object类中主要包括clone()、finalize()、equals()、toString()等方法。其中equals()、toString()较为常用。

所有的类都是Object类的子类,所以任何类都可以重写Object类中的方法。

1、getClass()方法
Class().getName();get

2、toString()方法 

功能:将一个对象返回为字符串形式,它会返回一个String实例。为对象提供一个特定的输出模式

 

3、equals()方法 

 equals()方法比较的是两个对象的实际内容。要想真正做到比较,需要在自定义类中重写equals()方法

7.3 类的多态 
 

多态意为一个名字可具有多种语义。利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。

类的多态可以从两个方面体现:一是方法的重载,二是类的上下转型。

7.3.1 方法的重载


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

 重载与重写是两个完全不同的概念,重载主要用于一个类内实现若干重载的方法。这些方法的名称相同而参数形势不同;而重写主要用于子类继承父类时,重新实现父类中的非私有方法。

7.3.2 向上转型 
把子类对象赋值给父类类型的变量,这种技术被称为“向上转型”。

在执行向上转型操作时,父类的对象无法调用子类独有的属性或者方法。
 

class Quadrangle {                             //四边形类
     public static void draw( Quadrangle q) {  //四边形类中的方法
             //SomeSentence
    }
 }
public class Parallelogram extends Quadrangle {  //平行四边形类,继承了四边形类
     public class void main(String args[]) {     //实例化平行四边形类对象引用
           Parallelogram p = new  Parallelogram();//调用父类方法
            draw(p);
     }
}

7.3.3 向下转型

通过向上转型可以推理出向下转型是将较抽象的类转换为较具体的类。

向下转型通常会出现问题:将父类对象直接赋予子类,会发生编译器错误,因为父类对象不一定是子类的实例。

越是具体的对象具有的特性越多,越抽象的对象具有的特性越少。

 class Restaurant  {
	public static void draw( Restaurant q) {
		//SomeSentence
	}
 }
   public class parallelogram extends  Restaurant {
	   public static void main(String[] args[]) {       
			       draw(new parallelogram () );
			       //将平行四边形类对象看作是四边形对象,称为向上转型操作
			       Restaurant q = new  parallelogram();
			       parallelogram p=q; //将父类对象赋予子类对象
	
                 //修改:parallelogram q= (parallelogram) q;		      
 
	}
 
}

7.3.4 instanceof 关键字

myobject instanceof ExampleClass

 class Quadrangle  {
	public static void draw(Quadrangle q) {
		//SomeSentence
	}
 }
class Square extends Quadrangle {
         //SomeSentence
class Anything {
       //SomeSentence
   public class parallelogram extends Quadrangle  {
	   public static void main(String[] args[]) {
                   Quadrangle q = new  Quadrangle         //实例化父类对象
                   //判断父类对象是否为Parallelogram子类的一个实例
                   if (q instanceof Parallelogram) {
                    Parallelogram p = (Parallelogram)  q;  //进行向下转型操作  
			       //判断父类对象是否为Parallelogram子类的一个实例
			       if (q instanceof Square) {
                    Square s = (Sauare) q;             //进行向下转型操作
                    }
                    //由于q对象不为Aaything类的对象,所以这条语句是错误的
                    //System.out.println(q instanceof Anything);		        
 
	}
 
}

注意:instanceof是Java语言的关键字,在Java中的关键字都为小写。 

7.4 抽象类与接口
7.4.1 抽象类与抽象方法
在解决实际问题时,一般将父类定义为抽象类,需要使用这个父类进行继承与多态处理。

在Java语言中设置抽象类不可以实例化对象,因为图形类不能抽象出任何一种具体图像,但它的子类却可以。
 

[权限修饰符]  abstract  class 类名  {undefined

         类体

}

[权限修饰符]  abstract  方法返回值类型  方法名(参数列表);

 注意:构造方法不能定义为抽象方法。

 public abstract class Market {undefined
 
public String name;     //商场名称
 
public String goods;     //商场名称
 
public abstract void shop();     //抽象方法,用来输出信息
————————————————
版权声明:本文为CSDN博主「蕾蕾1」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_67214194/article/details/124034922 public abstract class Market {undefined
 
public String name;     //商场名称
 
public String goods;     //商场名称
 
public abstract void shop();     //抽象方法,用来输出信息

 定义一个TaobaoMarket类,继承自Market抽象类,实现其中的shop抽象方法,代码如下:

public class TaobaoMarket extends Market {undefined
 
@Override
 
public void shop()  {undefined
 
//TODO Auto-generated method stub
 
System.out.println(name+"网购"+goods);
 
          }
 
}

  定义一个WallMarket类,继承自Market抽象类,实现其中的shop抽象方法,代码如下:

public class WallMarket extends Market {undefined
 
@Override
 
public void shop()  {undefined
 
//TODO Auto-generated method stub
 
System.out.println(name+"实体店购买"+goods);
 
          }
 
}
public class GOShopping
{
     public stadtic void main(String[] args)
    {
    Market market = new WallMarket();//使用费派生类对象创建抽象对象
    Market.name = "沃尔玛";
    market.goods = "七匹狼西服"; 
    market.shop =();
    market = new TaobaoMarket();//使用费派生类对象创建抽象对象
    market.name = "淘宝";
    market.goods = "韩都衣舍花裙";
    market.shop();
    }
}

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

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

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

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

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

 注意:构造方法不能定义为抽象方法。


7.4.2 接口的声明及实现


接口是抽象类的延申,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。

接口使用关键字interface进行定义,其语法如下:

一个接口实现一个接口可以使用implements关键字,

一个接口实现一个接口可以使用implements关键字,代码如下: 

public class Parallelogram extends Quadrangle  implements drawTest {undefined

...//

}

 

7.4.3 多重继承 

通过接口实现多重继承的语法如下:

class 类名 implements 接口1,接口2,...,接口n

 通过类实现多个接口模拟家庭成员的继承关系。

public interface IFather {    //定义一个接口

void smoking();     //抽烟的方法

void goFishing();   //钓鱼的方法

}

 定义一个IMother接口,并在其中定义两个方法wacthTV和cooking,代码如下:

public interface IMother {    //定义一个接口

  void wacthTV();   //看电视的方法

void cooking();       //做饭的方法

 创建名称为Me类,继承IFather和IMother两个接口

public class Me implements IFather, IMother { //继承IFather接口和IMother接口
	public void wacthTV()  {                  //重写wacthTV()方法
		System.out.println("我喜欢看电视");
	}
	public void cooking() {                  //重写cooking()方法  
		System.out.println("我喜欢做饭");
	}
	public void smoking() {                   //重写smoking()方法
		System.out.println("我喜欢抽烟");
	}
	public void goFishing() {                  //重写goFishing()方法
		System.out.println("我喜欢钓鱼");
	}
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		IFather fater = new Me();              //通过子类创建IFather接口对象
		System.out.println("爸爸的爱好:");
		father.smoking();  //使用接口对象调用子类中实现的方法
		father.goFishing();
		Mother mater = new Me();            //通过子类创建IMother接口对象
		System.out.println("\n妈妈的爱好:");
        mather.cooking();     //使用接口对象调用子类中实现的方法
        mather.wacthTV();
	}
 
}

7.4.4 区分抽象类与接口
抽象类和接口的区别主要有以下几点:

(1)子类·只能继承一个抽象类,但可以实现任意多个接口。

(2)一个类要实现去一个接口必须实现接口中的所有方法,而抽象类不必。

(3)抽象类中的成员变量是可以各种类型,而接口中的成员变量只能是public static final的。

(4)接口中只能定义抽象方法,而抽象类中可以定义非抽象方法。

(5)抽象类中可以有静态方法和静态代码块等,接口中不可以。

(6)接口不能被实例化,没有构造方法,但抽象类可以有构造方法。

7.5 访问控制
7.5.1 访问控制符
所有访问控制符时,需要遵循以下原则。

(1)大部分顶级类都使用public修饰。

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

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

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

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

7.5.2 Java类包
在Java中采用类包机制非常重要,类包不仅可以解决类名冲突问题,还可以在开发庞大的应用程序时,帮助开发人员管理庞大的应用程序组件,方便软件复用。

package 包名1 [.包名2[.包名3...] ];

注意:Java包的命名规则是全部使用小写字母,另外,由于包名将转换为文件的名称,所以包名不包括特殊字符

 使用包中的类,其语法如下:

import  包名1 [.包名2[.包名3...] ].类名;

 import  com.lzw.*;       //指定 com.lzw包中的所有类在程序中都可以使用

 import  com.lzw.Math        ///指定 com.lzw包中的Math类在程序中可以使用
 

7.5.3 final 关键字 

1.final类

 定义为final的类不能被继承

final的语法如下:

final class 类名{ }

 2.final 方法

 final方法不能被覆盖,定义一个为private的方法隐式被指定为final类型,这样无需将一个定义为private的方法再定义为final类型,例如下面:

 

3、final 变量

final 关键字可用于变量声明(定义的变量必须在声明时对其进行赋值操作) ,一旦该变量被设定,就不可以再改变该变量的值。

final double PI=3.14;

 

 

7.6  内部类
7.6.1 成员内部类


1、成员内部类简介

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

在内部类中可以随意使用外部类的成员方法以及成员变量。

成员内部类的语法如下:

public class OuterClass {      //外部类

   private class InnerClass  {   //内部类

           //...

    }

}
 

 例如,在主方法中实例化一个内部类对象。

public class void main(String args[]) {undefined

OuterClass out = new OuterClass();

OuterClass.innerClass in =out.doit();

OuterClass.innerClass in2=out.new innerClass();  //实例化内部类对象
 
 

 3、使用this关键字获取内部类与外部类的引用

 如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字。

使用成员内部类时,应该遵循以下原则:

(1)可以有各种修饰符,可以用private、public、protectd、static、final 、abstract等修饰符。

(2)如果有内部类有static限定,就是类级别的,否则为对象级别.类级别可以通过外部类直接访问,对象级别需要先生成外部类的对象后才能访问;

(3)内部类不能同名;

(4)非静态内部类中不能声明任何static成员;

(5)内部类可以互相调用;
 
 

public class TheSameName {
   private int x;
  private class Inner {
    private int x = 9;
    public void doit (int_x) {
            x++;                        //调用的是形参x
            this.x++;                  //调用内部类的变量x
            TheSameName.this.x++;     //调用外部类的变量x
       }
   }
}
实例内部类是指没有用 static 修饰的内部类,有的地方也称为非静态内部类。示例代码如下:
public class Outer {
    class Inner {
        // 实例内部类
    }
}
上述示例中的 Inner 类就是实例内部类。实例内部类有如下特点。
 
1)在外部类的静态方法和外部类以外的其他类中,必须通过外部类的实例创建内部类的实例。
public class Outer {
    class Inner1 {
    }
    Inner1 i = new Inner1(); // 不需要创建外部类实例
    public void method1() {
        Inner1 i = new Inner1(); // 不需要创建外部类实例
    }
    public static void method2() {
        Inner1 i = new Outer().new inner1(); // 需要创建外部类实例
    }
    class Inner2 {
        Inner1 i = new Inner1(); // 不需要创建外部类实例
    }
}
class OtherClass {
    Outer.Inner i = new Outer().new Inner(); // 需要创建外部类实例
}
2)在实例内部类中,可以访问外部类的所有成员。
public class Outer {
    public int a = 100;
    static int b = 100;
    final int c = 100;
    private int d = 100;
    public String method1() {
        return "实例方法1";
    }
    public static String method2() {
        return "静态方法2";
    }
    class Inner {
        int a2 = a + 1; // 访问public的a
        int b2 = b + 1; // 访问static的b
        int c2 = c + 1; // 访问final的c
        int d2 = d + 1; // 访问private的d
        String str1 = method1(); // 访问实例方法method1
        String str2 = method2(); // 访问静态方法method2
    }
    public static void main(String[] args) {
        Inner i = new Outer().new Inner(); // 创建内部类实例
        System.out.println(i.a2); // 输出101
        System.out.println(i.b2); // 输出101
        System.out.println(i.c2); // 输出101
        System.out.println(i.d2); // 输出101
        System.out.println(i.str1); // 输出实例方法1
        System.out.println(i.str2); // 输出静态方法2
    }
}
提示:如果有多层嵌套,则内部类可以访问所有外部类的成员。
 
3)在外部类中不能直接访问内部类的成员,而必须通过内部类的实例去访问。如果类 A 包含内部类 B,类 B 中包含内部类 C,则在类 A 中不能直接访问类 C,而应该通过类 B 的实例去访问类 C。
 
4)外部类实例与内部类实例是一对多的关系,也就是说一个内部类实例只对应一个外部类实例,而一个外部类实例则可以对应多个内部类实例。
 
如果实例内部类 B 与外部类 A 包含有同名的成员 t,则在类 B 中 t 和 this.t 都表示 B 中的成员 t,而 A.this.t 表示 A 中的成员 t。
public class Outer {
    int a = 10;
    class Inner {
        int a = 20;
        int b1 = a;
        int b2 = this.a;
        int b3 = Outer.this.a;
    }
    public static void main(String[] args) {
        Inner i = new Outer().new Inner();
        System.out.println(i.b1); // 输出20
        System.out.println(i.b2); // 输出20
        System.out.println(i.b3); // 输出10
    }
}
5)在实例内部类中不能定义 static 成员,除非同时使用 final 和 static 修饰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值