第一章

第二章
变量:

  1. 静态变量在静态和非静态方法中访问情况:
  2. 静态变量
    可以直接在静态方法和非静态方法中直接使用
    Public calss Cal{
    static int num;
    }
  3. 非静态变量
    可以直接在非静态方法中直接使用
    不能在静态方法中直接使用,可以先创建对象在调用
    第三章
    1.面向对象三大特征:
    封装,继承,多态;
    2.方法重载规则:
  4. 在同一个类中
  5. 方法名必须相同
  6. 方法的参数类不同 (和返回值类型没有关系)
    3.访问修饰符:
     对Java中的修饰符一直记不住,现在结合网上的一些资料进行总结,并重点说明一下protected修饰符。
    一. Java中的访问修饰符
      Java面向对象的基本思想之一是封装细节并且公开接口。Java语言采用访问控制修饰符来控制类及类的方法和变量的访问权限,从而向使用者暴露接口,但隐藏实现细节。访问控制分为四种级别:
      (1)public: 用public修饰的类、类属变量及方法,包内及包外的任何类(包括子类和普通类)均可以访问;
      (2)protected: 用protected修饰的类、类属变量及方法,包内的任何类及包外那些继承了该类的子类才能访问(此处稍后解释),protected重点突出继承;
      (3)default: 如果一个类、类属变量及方法没有用任何修饰符(即没有用public、protected及private中任何一种修饰),则其访问权限为default(默认访问权限)。默
       认访问权限的类、类属变量及方法,包内的任何类(包括继承了此类的子类)都可以访问它,而对于包外的任何类都不能访问它(包括包外继承了此类的子类)。default重点突出包;
      (4)private: 用private修饰的类、类属变量及方法,只有本类可以访问,而包内包外的任何类均不能访问它。 
      网上一些资料及一些书上用表格对java访问修饰符做了清楚的总结,如下表所示:
    访问级别 访问控制修饰符 同类 同包 子类 不同的包
    公开 public √ √ √ √
    受保护 protected √ √ √ --
    默认 没有访问控制修饰符 √ √ -- --
    私有 private √ -- -- --
      本人以为该表有些问题交代不清楚,如访问修饰符protected中,不同的包不可以访问,而子类可以访问,那试问位于不同包中的子类是能访问还是不能访问呢?因此本人在自
    己理解的基础上,为了自己理解方便,容易记忆,重新整理了一个表格如下: 
    访问级别 访问控制修饰符 同类 同包不同类(不含子类) 同包子类 不同包不同类
    (不含子类) 不同包子类
    公开 public √ √ √ √ √
    受保护 protected √ √ √ -- √(注意)
    默认 没有访问控制修饰符 √ √ √ -- --
    私有 private √ --- --- -- --
      重要总结:通过上面的分析,我们可以看到:
       1. public、private和protected对我们来说没有任何异议。
       2. 顶层类只能用public访问修饰符和default(默认)访问修饰符修饰,其中用默认修饰符修饰的类(及没有任何修饰符的类,如class B{})不能被其他包中的类继承,这也说明了default(默认)访问修饰符突出的是包权限

   3. protected:本人做了一次实验,发现在不同包的子类中,new一个父类对象,并用该父类对象去访问父类中的用protected修饰的类属变量和方法时不能访问,而new一个子类对象时,子类对象可以访问(说明protected修饰的类可以被其他包中的类继承)。也可以在子类重写父类的方法中使用super关键字调用。这岂不是和上面表格中的总结(红色对勾)冲突了?本人也是百思不得其解。最后在网上找到了一个相对比较认可的解释,如下:    
  protected修饰符的修饰的成员变量和方法也称为受保护的成员变量和方法, 受保护的成员变量和方法可以在本类或同一个包中的其它类(包括子类)中通过类的实例进行访问,也可以被同一个包中的类或不同包中的类继承,但是不能在不同包中的其它类(包括子类)中通过类的实例进行访问。
  4. 如果一个类使用public修饰,那该类的类名必须与他所在的源文件名相同。一个.java源文件中有且只有一个public类,顶层类只能用public和默认修饰符(即无修饰符)修饰;
  5. final修饰的类不能被继承,没有子类。
  6. abstract修饰的类不能被实例化,必须被子类继承。类只要有一个抽象方法就必定是抽象类,但抽象类不一定要有抽象方法。
最终总结,就一句话:protected修饰符所修饰的类(这句话中指父类)属成员变量和方法,只可以被子类访问,而不管子类是不是和父类位于同一个包中。default修饰符所修饰的类属成员变量和方法,只可被同一个包中的其他类访问,而不管其他类是不是该类的子类。protected属于子类限制修饰符,而default属于包限制修饰符。

4.封装步骤:
1) 修改属性的可见性---》设置为private
2) 创建getter,setter方法,设置取值范围
3) 在main函数通过getter,setter调用
2.如何从现实世界抽象出类:
找出分类(分析出类) 第二:找出类的特征(分析类的相关属性) 第三:找出类的行为(分析类的方法)
第四章
1.继承的优点与实现:
1.继承关系是传递的。若类C继承类B,类B继承类A,则类C既有从类zhiB那里继承下来dao的属性与方法,也有从类A那里继承下来的属性与方法,继承来的属性和方法尽管是隐式的,但仍是类C的属性和方法。继承是在一些比较一般的类的基础上构造、建立和扩充新类的最有效的手段;
2、继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系;继承提供了软件复用功能。这种做法能减小代码和数据的冗余度,大大增加程序的重用性;提供多重继承机制。出于安全性和可靠性的考虑,仅支持单重继承,而通过使用接口机制来实现多重继承。
语法:
Public class 子类名 extends 父类{
}
3.可以继承内容:
1)成员变量
2,)方法
2.继承的使用:
继承:从多个具体的子类中抽取出相同的属性以及行为,组合成一个新的父类 然后让这些具体的子类继承这个父类
继承关键字:extends
语法格式
修饰符 class 子类 extends 父类
父类中公开的属性以及方法都能被子类继承
注意:私有的属性不能被继承
私有的方法不能被继承
注意:父类只能有1个,子类可以有多个
java是一种单继承语言,但是它支持继承链
C++是多继承
构造方法不能被继承
不能继承父类使用的默认修饰符
继承的优点:
1:提高代码的复用性
继承的缺点:
1:提高了代码的耦合性
开发原则:高内聚,低耦合
内聚:自己完成某件事的能力
耦合:类和类之间关系

3.构造方法的执行过程
1:创建子类对象,先去调用父类的构造方法,再调用自己构造方法
2:java中的顶级父类是Object
3:如果一个类没有继承其他类,那么它默认继承Object
4:无论new哪一个对象,都会先初始化Object
5:如果子类初始化的时候,没有给属性赋值,那么它获取的是父类的属性值,如果子类给属性赋值了,那么就会覆盖父类属性的值
6:初始化子类之前,一定要先初始化父类的值
7:构造方法不能被继承
8:成员方法中不能调用父类构造方法
4.子父类对于成员变量的处理

1:父类有,子类也有,获取的是子类的
2:父类有,子类没有,获取的是父类的
3:父类没有,子类有,获取的是子类的
4:父类没有,子类没有,编译报错
子父类对于成员方法的处理
1:父类有,子类也有,获取的是子类的
2:父类有,子类没有,获取的是父类的
3:父类没有,子类有,获取的是子类的
4:父类没有,子类没有,编译报错

5.方法的重写:
在重写方法时,需要遵循下面的规则:
• 参数列表必须完全与被重写的方法参数列表相同。
• 返回的类型必须与被重写的方法的返回类型相同(Java1.5 版本之前返回值类型必须一样,之后的 Java 版本放宽了限制,返回值类型必须小于或者等于父类方法的返回值类型)。
• 访问权限不能比父类中被重写方法的访问权限更低(public>protected>default>private)。
• 重写方法一定不能抛出新的检査异常或者比被重写方法声明更加宽泛的检査型异常。例如,父类的一个方法声明了一个检査异常 IOException,在重写这个方法时就不能抛出 Exception,只能拋出 IOException 的子类异常,可以抛出非检査异常。

另外还要注意以下几条:

• 重写的方法可以使用 @Override 注解来标识。
• 父类的成员方法只能被它的子类重写。
• 声明为 final 的方法不能被重写。
• 声明为 static 的方法不能被重写,但是能够再次声明。
• 构造方法不能被重写。
• 子类和父类在同一个包中时,子类可以重写父类的所有方法,除了声明为 private 和 final 的方法。
• 子类和父类不在同一个包中时,子类只能重写父类的声明为 public 和 protected 的非 final 方法。
• 如果不能继承一个方法,则不能重写这个方法。
一、方法重写(0veriding)
在Java程序中,类的继承关系可以产生一个子类,子类继承父类,它具备了父类所有的特征,继承了父类所有的方法和变量。
子类可以定义新的特征,当子类需要修改父类的一些方法进行扩展,增大功能,程序设计者常常把这样的一种操作方法称为重写,也叫称为覆写或覆盖。
重写体现了Java优越性,重写是建立在继承关系上,它使语言结构更加丰富。在Java中的继承中,子类既可以隐藏和访问父类的方法,也可以覆盖继承父类的方法。
在Java中覆盖继承父类的方法就是通过方法的重写来实现的。所谓方法的重写是指子类中的方法与父类中继承的方法有完全相同的返回值类型、方法名、参数个数以及参数类型。
这样,就可以实现对父类方法的覆盖。如果子类将父类中的方法重写了,调用的时候肯定是调用被重写过的方法,那么如果现在一定要调用父类中的方法该怎么办呢?
此时,通过使用super关键就可以实现这个功能,super关键字可以从子类访问父类中的内容,如果要访问被重写过的方法,使用“super.方法名(参数列表)”的形式调用。
如果要使用super关键字不一定非要在方法重写之后使用,也可以明确地表示某个方法是从父类中继承而来的。使用super只是更加明确的说,要从父类中查找,就不在子类查找了。
二.重写规则
在重写方法时,需要遵循以下的规则:
(1) 父类方法的参数列表必须完全与被子类重写的方法的参数列表相同,否则不能称其为重写而是重载。
(2) 父类的返回类型必须与被子类重写的方法返回类型相同,否则不能称其为重写而是重载。..
(3) Java中规定,被子类重写的方法不能拥有比父类方法更加严格的访问权限。编写过Java程序的人就知道,
父类中的方法并不是在任何情况下都可以重写的,当父类中方法的访问权限修饰符为private时,该方法只能被自己的类访问,
不能被外部的类访问,在子类是不能被重写的。如果定义父类的方法为public,在子类定义为private,程序运行时就会报错。
(4) 由于父类的访问权限修饰符的限制一定要大于被子类重写方法的访问权限修饰符,而private权限最小。
所以如果某一个方法在父类中的访问权限是private,那么就不能在子类中对其进行重写。如果重新定义,也只是定义了一个新的方法,不会达到重写的效果。
(5) 在继承过程中如果父类当中的方法抛出异常,那么在子类中重写父类的该方法时,也要抛出异常,
而且抛出的异常不能多于父类中抛出的异常(可以等于父类中抛出的异常)。换句话说,重写方法一定不能抛出新的检查异常,
或者比被重写方法声明更加宽泛的检查型异常。例如,父类的一个方法申明了一个检查异常IOException,在重写这个方法时就不能抛出Exception,
只能抛出IOException的子类异常,可以抛出非检查异常。同样的道理,如果子类中创建了一个成员变量,
而该变量和父类中的一个变量名称相同,称作变量重写或属性覆盖。但是此概念一般很少有人去研究它,因为意义不大。

三、方法重载(Overloading)
方法重载是让类以统一的方式处理不同类型数据的一种手段。调用方法时通过传递给它们的不同个数和类型的参数来决定具体使用哪个方法,这就是多态性。
所谓方法重载是指在一个类中,多个方法的方法名相同,但是参数列表不同。参数列表不同指的是参数个数、参数类型或者参数的顺序不同。
方法的重载在实际应用中也会经常用到。不仅是一般的方法,构造方法也可以重载。
在方法重载时,方法之间需要存在一定的联系,因为这样可以提高程序的可读性,一般只重载功能相似的方法。
重载是指我们可以定义一些名称相同的方法,通过定义不同的参数来区分这些方法,然后再调用时,Java虚拟机就会根据不同的参数列表来选择合适的方法执行
。也就是说,当一个重载方法被调用时,Java用参数的类型或个数来决定实际调用的重载方法。因此,每个重载方法的参数的类型或个数必须是不同。
虽然每个重载方法可以有不同的返回类型,但返回类型并不足以区分所使用的是哪个方法。
当Java调用一个重载方法是,参数与调用参数匹配的方法被执行。在使用重载要注意以下的几点:
1.在使用重载时只能通过不同的参数列表,必须具有不同的参数列表。
2.不能通过访问权限、返回类型、抛出的异常进行重载。
3.方法的异常类型和数目不会对重载造成影响。
4.可以有不同的返回类型,只要参数列表不同就可以了。
5.可以有不同的访问修饰符。
6.可以抛出不同的异常。

四、方法重写与方法重载的区别

1.super()的使用实例 一一一子类重写父类的方法

  1. public class A {
  2.  private String nameA="A";
    
  3.  public void getName() {
    
  4.  	System.out.println("父类"+nameA);
    
  5.  }
    
  6.  public static void main(String[] args) {
    
  7.  }
    
  8. }
  9. public class B extends A{
  10. private String nameB="B";
    
  11. @Override
    
  12. public void getName() {
    
  13. 	System.out.println("子类"+nameB);
    
  14. 	super.getName();
    
  15. }
    
  16. public static void main(String[] args) {
    
  17. 	B b=new B();
    
  18. 	b.getName();
    
  19. }
    
  20. }
    运行结果:

结果分析:
在子类B中,我们重写了父类的getName方法,如果在重写的getName方法中我们去调用了父类的相同方法,必须要通过super关键字显示的指明出来。
如果不明确出来,按照子类优先的原则,相当于还是再调用重写的getName()方法,此时就形成了死循环,执行后会报java.lang.StackOverflowError异常。如下图所示:

2.super()的使用实例 一一一子类重写父类的变量

  1. public class A {
  2.   String nameA="A";
    
  3. }
  4. public class B extends A{
  5.   String nameA="B";
    
  6. public void getName() {
    
  7. 	System.out.println("子类"+nameA);
    
  8. 	System.out.println("父类"+super.nameA);
    
  9. }
    
  10. public static void main(String[] args) {
    
  11. 	B b=new B();
    
  12. 	b.getName();
    
  13. }
    
  14. }
    运行结果:

此时子类B中有一个和父类一样的字段(也可以说成父类字段被隐藏了),为了获得父类的这个字段我们就必须加上super,如果没有加,直接写成name = name;不会报错,只是会警告,表示此条语句没有任何意义,因为此时都是访问的子类B里面的那么字段。
我们通过super是不能访问父类private修饰的变量和方法的,因为这个只属于父类的内部成员,一个对象是不能访问它的private成员的。

3.super()的使用实例 一一一在子类的构造方法中
编译器会自动在子类构造函数的第一句加上 super(); 来调用父类的无参构造器;此时可以省略不写。如果想写上的话必须在子类构造函数的第一句,可以通过super来调用父类其他重载的构造方法,只要相应的把参数传过去就好。

因此,super的作用主要在下面三种情况下:
1、调用父类被子类重写的方法;
2、调用父类被子类重定义的字段(被隐藏的成员变量);
3、调用父类的构造方法;
其他情况,由于子类自动继承了父类相应属性方法,关键字super可以不显示写出来。
4.关于构造方法中super()
第一种情况:编译不通过

分析:
如果一个类中没有写任何的构造方法,JVM会生成一个默认的无参构造方法。在继承关系中,由于在子类的构造方法中,第一条语句默认为调用父类的无参构造方法(即默认为super(),一般这句话省略了)。所以当在父类中定义了有参构造函数,都是没有定义无参构造函数时,IDE会强制要求我们定义一个相同参数类型的构造器。
在本例中JVM默认给B加了一个无参构造方法,而在这个方法中默认调用了super(),但是父类中并不存在该构造方法
第二种情况:编译不通过

同样编译错误,相同的道理,虽然我们在子类中自己定义了一个构造方法,但是在这个构造方法中还是默认调用了super(),但是父类中并不存在该构造方法
第三种情况:成功编译通过

  1. public class A {
  2.  public A(String s) {
    
  3.  }
    
  4. }
  5. public class B extends A{
  6.  public B(String s) {
    
  7. 	super(s);
    
  8. }
    
  9. }
    分析:
    所以,只要记住,在子类的构造方法中,只要里面没有显示的通过super去调用父类相应的构造方法,默认都是调用super(),即无参构造方法,因此要确保父类有相应的构造方法
  10. final用法
      在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。下面就从这三个方面来了解一下final关键字的基本用法。
    1.修饰类
      当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。
      常用到的String、Boolean、Byte、Integer类就是一个final类,被final修饰的类也被成为断子绝孙类。
    2.修饰方法
      使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。
      因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。
    3.修饰变量
      修饰变量是final用得最多的地方,也是本文接下来要重点阐述的内容。首先了解一下final变量的基本语法:
      对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
      当用final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后,就不能再被赋值了。
posted on 2020-10-21 19:34  血染白衣  阅读(56)  评论(0)    收藏  举报