Java入门概念梳理之二

2019-06-15 00:00:00 梳理 入门 之二


OOP

Java 继承(基于类不如JS的基于原型)

  • 类的继承
    
    class Parent{

}
class Child extends Parent{
}
//动物类
public class Animal {
private String name;
private int id;
public Animal(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+”正在吃”);
}
public void sleep(){
System.out.println(name+”正在睡”);
}
public void introduction() {
System.out.println(“大家好!我是” + id + “号” + name + “.”);
}
}
//Penguin
public class Penguin extends Animal {
public Penguin(String myName, int myid) {
super(myName, myid);
}
}
//Mouse
public class Mouse extends Animal {
public Mouse(String myName, int myid) {
super(myName, myid);
}
}

- 继承特性:
    +  子类拥有父类非private的属性,方法。
    +  子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
    +  子类可以用自己的方式实现父类的方法。
    +  Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,
    例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性。
    +  提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)

- 继承关键字
继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,
当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。
    + extends: 只能继承一个类。      
    + implements:可以同时继承多个接口(接口跟接口之间采用逗号分隔)
    public interface A {
    public void eat();
    public void sleep();
    }

    public interface B {
    public void show();
    }

    public class C implements A,B {
    }
    ```
+ super and this:super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
                 this关键字:指向自己的引用。
```
  public class SuperDemo {
      public static void main(String []args) {
          new SubClass().showMessage();
      }
  }

  class SuperClass {
      int i = 50;
  }

  class SubClass extends SuperClass {
      int i =100;
      public void showMessage() {
          System.out.printf("super.i = %d, this.i = %d\n", super.i, this.i);
      }
  }
```
+ final:把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写
  • 构造器:
    子类不能继承父类的构造器(构造方法或者构造函数),但是父类的构造器带有参数的,
    则必须在子类的构造器中显式地通过super关键字调用父类的构造器并配以适当的参数列表。
    如果父类有无参构造器,则在子类的构造器中用super调用父类构造器不是必须的,
    如果没有使用super关键字,系统会自动调用父类的无参构造器。


Java Override(重写)/Overload(重载)

Override

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,
但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。

class Animal{
   public void move(){
      System.out.println("动物可以移动");
   }
}

class Dog extends Animal{
   public void move(){
      System.out.println("狗可以跑和走");
   }
}

public class TestDog{
   public static void main(String args[]){
      Animal a = new Animal(); // Animal 对象
      Animal b = new Dog(); // Dog 对象

      a.move();// 执行 Animal 类的方法

      b.move();//执行 Dog 类的方法
   }
}
//
动物可以移动
狗可以跑和走
  • 重写规则
    • 参数列表必须完全与被重写方法的相同;
    • 返回类型必须完全与被重写方法的返回类型相同;
    • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
    • 父类的成员方法只能被它的子类重写。
    • 声明为final的方法不能被重写。
    • 声明为static的方法不能被重写,但是能够被再次声明。
    • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
    • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
    • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
    • 构造方法不能被重写。
    • 如果不能继承一个方法,则不能重写这个方法。
  • super:当需要在子类中调用父类的被重写方法时,要使用super关键字。
    
    class Animal{
    public void move(){
      System.out.println("动物可以移动");
    }
    }

class Dog extends Animal{
public void move(){
super.move(); // 应用super类的方法
System.out.println(“狗可以跑和走”);
}
}

public class TestDog{
public static void main(String args[]){
Animal b = new Dog(); // Dog 对象
b.move(); //执行 Dog类的方法

}
}
//
动物可以移动
狗可以跑和走

### 重载overload
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
- 规则:
    + 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
    + 被重载的方法可以改变返回类型;
    + 被重载的方法可以改变访问修饰符;
    + 被重载的方法可以声明新的或更广的检查异常;
    + 方法能够在同一个类中或者在一个子类中被重载。
    + 无法以返回值类型作为重载函数的区分标准。

public class Overloading {
public int test(){
System.out.println(“test1”);
return 1;
}

public void test(int a){
    System.out.println("test2");
}   

//以下两个参数类型顺序不同
public String test(int a,String s){
    System.out.println("test3");
    return "returntest3";
}   

public String test(String s,int a){
    System.out.println("test4");
    return "returntest4";
}   

public static void main(String[] args){
    Overloading o = new Overloading();
    System.out.println(o.test());
    o.test(1);
    System.out.println(o.test(1,"test3"));
    System.out.println(o.test("test4",1));
}

}

- 对比
|区别点|重载|重写|
|参数列表|必改|不可改|
|返回类型|可改|不可改|
|异常|可改|可以减少或删除,一定不能抛出新的或者更广的异常|
|访问|可改|一定不能做更严格的限制(可以降低限制)|
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载是一类中多态性的一种表现。

# Java 多态:同一个行为具有多个不同表现形式或形态的能力,是同一个接口,使用不同的实例而执行不同操作
![多态][http://www.runoob.com/wp-content/uploads/2013/12/dt-java.png]
- 优点
    1. 消除类型之间的耦合关系
    2. 可替换性
    3. 可扩充性
    4. 接口性
    5. 灵活性
    6. 简化性
- 多态存在的三个必要条件
    1. 继承     
    2. 重写
    3. 父类引用指向子类对象

public class Test {
public static void main(String[] args) {
show(new Cat());
show(new Dog());

  Animal a = new Cat();  
  a.eat();               
  Cat c = (Cat)a;       
  c.work();        

}

public static void show(Animal a)  {
  a.eat();  
    if (a instanceof Cat)  {  
        Cat c = (Cat)a;  
        c.work();  
    } else if (a instanceof Dog) { 
        Dog c = (Dog)a;  
        c.work();  
    }  
}  

}

abstract class Animal {
abstract void eat();
}

class Cat extends Animal {
public void eat() {
System.out.println(“eatting fish”);
}
public void work() {
System.out.println(“cathing mouse”);
}
}

class Dog extends Animal {
public void eat() {
System.out.println(“eatting bone”);
}
public void work() {
System.out.println(“keep the door”);
}
}

- 虚方法
- 多态的实现
    + 重写
    + 接口
    + 抽象类和抽象方法

# Java 抽象类
OOP上,所有对象都是用来类描绘的,反之不一定,若类中无包含足够信息来描绘一个具体对象该类即抽象类
除不能实例化对象之外,其它功能健在,成员变量成员方法和构造方法的访问方式和普通类一样。
因抽象类不能实例化对象,故抽象类必须被集成才能被使用。父类包含了子类集合的常见方法,但父类本身是抽象的故不能使用这些方法。
Java中抽象类表示一种继承关系,一个类只能集成一个抽象类,而一个类可以实现多个接口。
### 抽象类

/ 文件名 : Employee.java /
public abstract class Employee
{
private String name;
private String address;
private int number;
public Employee(String name, String address, int number)
{
System.out.println(“Constructing an Employee”);
this.name = name;
this.address = address;
this.number = number;
}
public double computePay()
{
System.out.println(“Inside Employee computePay”);
return 0.0;
}
public void mailCheck()
{
System.out.println(“Mailing a check to ” + this.name

  • ” ” + this.address);
    }
    public String toString()
    {
    return name + ” ” + address + ” ” + number;
    }
    public String getName()
    {
    return name;
    }
    public String getAddress()
    {
    return address;
    }
    public void setAddress(String newAddress)
    {
    address = newAddress;
    }
    public int getNumber()
    {
    return number;
    }
    }
    
    - 总结:
    1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
    2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
    3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
    4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
    5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类


Java 封装(Encapsulation):一种将抽象性函式接口的实作细节部份包装、隐藏起来的方法。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

  • 优点:

    1. 良好的封装能够减少耦合。
    2. 类内部的结构可以自由修改。
    3. 可以对成员变量进行更精确的控制。
    4. 隐藏信息,实现细节。

      实现Java封装的步骤

    5. 修改属性的可见性来限制对属性的访问(一般限制为private)
      public class Person {
      private String name;//只能本类才能访问,其他类都访问不了
      private int age;
      }
    6. 对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问
      
      public class Person{
      private String name;
      private int age;
      ​
      public int getAge(){
      return age;
      }
      ​
      public String getName(){
      return name;
      }
      ​
      public void setAge(int age){
      this.age = age;
      }
      ​
      public void setName(String name){
      this.name = name;
      }
      }
      //实例
      public class EncapTest{

    private String name;
    private String idNum;
    private int age;

    public int getAge(){
    return age;
    }

    public String getName(){
    return name;
    }

    public String getIdNum(){
    return idNum;
    }

    public void setAge( int newAge){
    age = newAge;
    }

    public void setName(String newName){
    name = newName;
    }

    public void setIdNum( String newId){
    idNum = newId;
    }
    }

    
    *通常情况下,这些方法被称为getter和setter方法。任何要访问类中私有成员变量的类都要通过这些getter和setter方法*


Java 接口(Interface):一个抽象类型,是抽象方法的集合,接口通常以interface来声明

一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。
另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

  • 接口与类相似点:
    • 一个接口可以有多个方法。
    • 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
    • 接口的字节码文件保存在 .class 结尾的文件中。
    • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。
  • 接口与类的区别:
    • 接口不能用于实例化对象。
    • 接口没有构造方法。
    • 接口中所有的方法必须是抽象方法。
    • 接口不能包含成员变量,除了 static 和 final 变量。
    • 接口不是被类继承了,而是要被类实现。
    • 接口支持多重继承。
  • 接口特性
    • 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
    • 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误。
    • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
  • 抽象类和接口的区别
    1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
    2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
    3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
    4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

      接口的声明

      
      [可见度] interface 接口名称 [extends 其他的类名] {
      // 声明变量
      // 抽象方法
      }
      //实例
      /* 文件名 : NameOfInterface.java */
      import java.lang.*;
      //引入包

public interface NameOfInterface
{
//任何类型 final, static 字段
//抽象方法
}

- 接口有以下特性:
    + 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
    + 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键子。
    + 接口中的方法都是公有的。    
### 接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
实现一个接口的语法,可以使用这个公式:
``` ...implements 接口名称[, 其他接口, 其他接口..., ...] ...```
### 接口的继承
一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。

# Java package:为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间
- 包的作用
    1. 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
    2. 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,
    当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
    3. 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
- Java 使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等。

package pkg1[.pkg2[.pkg3…]];

package net.java.util
public class Something{

}

- 一个包(package)可以定义为一组相互联系的类型(类、接口、枚举和注释),为这些类型提供访问保护和命名空间管理的功能。
    + java.lang-打包基础的类
    + java.io-包含输入输出功能的函数
### 创建包

/ 文件名: Animal.java /
//在 animals 包中加入一个接口(interface):
package animals;

interface Animal {
public void eat();
public void travel();
}

### import关键字

import package1[.package2…].(classname|*);
package payroll;

public class Boss
{
public void payEmployee(Employee e)
{
e.mailCheck();
}
}


### package的目录树

--------------

# Java 高级

## Java 数据结构

- Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类:
    + 枚举(Enumeration)
    + 位集合(BitSet):位集合类实现了一组可以单独设置和清除的位或标志
    + 向量(Vector):和传统数组非常相似,但是Vector的大小能根据需要动态的变化。
    + 栈(Stack):栈(Stack)实现了一个后进先出(LIFO)的数据结构
    + 字典(Dictionary):是一个抽象类,它定义了键映射到值的数据结构
    + 哈希表(Hashtable):提供了一种在用户定义键结构的基础上来组织数据的手段。
    + 属性(Properties):表示了一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。
 *以上这些类是传统遗留的,在Java2中引入了一种新的框架-集合框架(Collection)*   

## Java 集合框架
- 集合框架被设计成要满足以下几个目标。
    + 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
    + 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
    + 对一个集合的扩展和适应必须是简单的。
- 集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:
    + 接口:是代表集合的抽象数据类型。接口允许集合独立操纵其代表的细节。在面向对象的语言,接口通常形成一个层次。
    + 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构。
    + 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。
    + 除了集合,该框架也定义了几个Map接口和类。Map里存储的是键/值对。尽管Map不是collections,但是它们完全整合在集合中。

## Java 泛型
va 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

## Java 序列化
## Java 网络编程
## Java 多线程编程
## Java Applet基础
## Java 文档注释
## Java 实例
## Java 8 新特性
## Java MySQL连接

相关文章