网上的教学很多,看视频非常浪费时间,看文字快点,快速捡起知识点,我只根据我学到的,集各种教学学习,把精华提取出来,把主要概念通俗的展示出来,基本常识就不介绍了,其他的资料谁看了都能看懂,只是java特有面向对象知识不好理解而已,但都是基础必须掌握。

温故而知新---陆续学习陆续更新中,你有更好的记忆和学习方法,请在评论区提出来大家一起交流,认真看完,一行行代码备注看完看懂,只要明白和理解就行,文字多记不住没关系,多看几遍就会了,保证学会,学不会找我。

前言:

学基础最基础的东西,完全一个没有学过的入门可以细细的看,你学过了,有经验了不要浪费时间,快速的把基础捡起来,然后去练习。

代码学完发现很简单,很多初学者搞不明白什么这个那个,其实是没有把概念记住,没有那么多为什么,为什么就这样做,就像小时候学数学,有很多的公式,刚开始学,我们只要死记公式,然后多练习,练习多了就不需要公式了,有时口算都能出来,到现在也不需要去理解公式为何是这样,不需要去深究它。后面你精通后在去专研它也可以。

比如在我的笔记里,里面有很多固定写法,你只需要记住就行,比如有class开头你就知道后面肯定是类对象,有new就是新建一个对象,List<>这样的你就知道是集合、泛型的概念等等,多多照着做,一百个人写一个相同的代码都可能有100个为什么这样写可以,这样写不可以,我能不能这样写的念头。

师傅领进门,修行看个人,同一套剑法,同一个师傅,100个学生的等级功力都不一样,更可况后面选择的职业和方向都不一样的,要想厉害就要多磨剑,多练,不然久不练剑法招式会忘光,代码也一样,你天天敲,敲个一年半载,其实来回敲的都是那些代码,换汤不换药,都一个套路,程序员你一个星期不写代码,你都不熟练甚至都不知道了,更可况你一个新入门的新手。

Java作为一种面向对象语言。学习java必须懂得基本概念如下:

  • 多态
  • 继承
  • 封装
  • 抽象
  • 对象
  • 静态
  • 实例/构造方法
  • 方法
  • 重载/重写
  • 接口
  • 内部类
  • 包类/包装类(自动封装/拆装)
  • GUI(界面、UI)
  • 异常

对象

(中国有12亿人,就有12亿对象,但是人只有一个)

对象就是我们周围的各种各样的事物。例如:衣服、盘子、宠物、朋友、电脑等。

对象是类的一个实例(对象不是指女朋友的哪个对象),是有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。

软件对象也有状态和行为。软件对象的状态就是属性,行为通过方法体现。

每个对象都有一些状态(属性)。例如:

衣服:{颜色,长度,面料…}。

猫:{名字,情绪,饥饿,}。

有些对象会作出一些行为。例如:

猫:{名字,情绪,疲劳,饥饿…

发怒,玩耍,吃食,睡觉…}。

对象的行为会改变对象的状态。例如:

玩耍 → 疲劳=True

睡觉 → 疲劳=False

吃食 → 饥饿=False

对象的状态会影响对象的行为。例如:

if( 饥饿 == False) → 吃食 return failure

创建对象

对象是根据类创建的。在Java中,使用关键字new创建一个新的对象。创建对象需要以下三步:

  • 第1步.声明:声明一个对象,包括对象名称和对象类型。如:int
  • 第2步.实例化:使用关键字new来创建一个对象。如:myDog =new Dog();
  • 第3步.初始化:使用new创建对象时,会调用构造方法初始化对象。如:a=new int(“tommy”)

下面是一个创建对象的例子: 

相当于:  Dog myDog;//定义一个,类似int a;

                  myDog = new Dog( "tommy" );//类似赋值

以上的两步可以一步写成:Dog myDog = new Dog( "tommy" );//new一个myDog对象

public class Dog{//对象小狗
   public Dog(String name){//用的构造方法
      //这个构造器仅有一个参数:name
      System.out.println("小狗的名字是 : " + name ); 
   }
   public static void main(String []args){
      // 下面的语句将创建一个Dog对象
      Dog myDog = new Dog( "tommy" );
   }
}

输出:

小狗的名字是 : tommy

类是对象的蓝图

类是对象的蓝图,对象是类的实例,如同绘图员可以绘制设备的蓝图,蓝图可以在制造实际设备时使用很多次。

类是软件的蓝图,你可以用类,来实例化许许多多个别的对象。

在类中定义了一套数据元素状态(属性)和一套行为(方法)。行为用来操作对象,以及完成相关对象之间的交互。

属性和方法都叫做成员。例如:交通工具对象必须保存两个属性:最大载重量和当前载重量;装载集装箱的方法要始终跟踪这两个属性。

类可以看成是创建Java对象的模板。

public class Dog{//对象狗,(声明类)
  
//以下是属性/状态,(声明属性)
 String breed;//种类 
 int age;//年龄 
 String color//颜色
  
//以下是dog类方法/行为,(声明方法)
 void barking(){//狗叫 
   //狗这个类的方法之一
 } 
 void hungry(){//饥饿
  //狗这个类的方法之一
 } 
 void sleeping(){//睡觉 
 //狗这个类的方法之一
 }

}

一个类可以包含以下类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。

构造方法

(主要是用来初始化参数,用更简单方式对实例变量进行赋值)

如:数字初始化设置为0、boolean类型设置为falsh,String设置为null等等,都需要初始化,这些就是构造方法

people p = new people();//new一个p对象,初始化people里的参数

每个类都有构造方法

如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法

在创建一个对象的时候,至少要调用一个构造方法

构造方法的名称必须与同名,一个类可以有多个构造方法。

下面是一个构造方法示例(声明类的方法),跟重载差不多:

public class Dog{//类(有多个构造方法)
    

    public Dog(){//构造方法 (与类同名)
    }
 
    public Dog(String name){
        // 这个构造器仅有一个参数:name
    }
}

访问实例变量和方法

通过已创建的对象来访问成员变量和成员方法,如下所示:

/* 实例化对象 */
ObjectReference = new Constructor();
/* 访问类中的变量 */
ObjectReference.variableName;
/* 访问类中的方法 */
ObjectReference.MethodName();

实例:

public class Puppy{
   int puppyAge;
   public Puppy(String name){
      // 这个构造器仅有一个参数:name
      System.out.println("小狗的名字是 : " + name ); 
   }
 
   public void setAge( int age ){
       puppyAge = age;
   }
 
   public int getAge( ){
       System.out.println("小狗的年龄为 : " + puppyAge ); 
       return puppyAge;
   }
 
   public static void main(String []args){
      /* 创建对象 */
      Puppy myPuppy = new Puppy( "tommy" );

      /* 通过方法来设定age */
      myPuppy.setAge( 2 );

      /* 调用另一个方法获取age */
      myPuppy.getAge( );

      /*你也可以像下面这样访问成员变量 */
      System.out.println("变量值 : " + myPuppy.puppyAge ); 
   }
}

输出:

小狗的名字是 : tommy
小狗的年龄为 : 2
变量值 : 2

静态

static,为了省内存,把相同的共性写在同一个地方,如图所示:

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象方法

例子:都共享一个数据,虽然two.room,但是用的还是one.room

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象方法_02

内部类:

(1)一个类被嵌套定义在另一个类中,那么这个类就被称为内部类,包含内部类的类被称为外部类;

(2)内部类相当于外部类的成员变量或方法;

如何构造内部类,在外部类的里面,相当于outer的成员变量

outer out = new outer();

//访问内部

outer.inter in = out.new.inter();//格式的写法,要记住

in.print();

固定写法:

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象类_03

分类如下:

(几种内部类的理解)

1.匿名内部类:比较特殊,没有名字,写法注意大括号结尾加分号“};”

  接口: 

interface outerI{

  public  void  show();//抽象方法,没有具体实现

  }

   写个main函数测试下:

public static void main(String[] args){
  
   outerI outer = new outerI(){//也可以直接写new outerI()
   //接口不能直接new,要加上大括号,这样就没有名字了
      
     @Override //重写方法,要重写接口的方法,接口的知识,接口的是抽象方法,要它具体实现普通方法
     public void show(){
       system.out.printfln(“这是匿名内部类的show”);
       }

    };//注意这里一定要加分号“;”,这是匿名内部类的格式写法

   outer.show();//访问匿名内部类

}

普通类继承匿名内部类:

class A impements outerI{//这个A才是类名,有名字
  
  @Override //重写
  public void show(){


  };

}

匿名内部类应用场景: 匿名内部类使用广泛,比如我们常用的绑定监听的时候

2.静态内部类:在前面加个static就是静态类了,要是内部类就是静态内部类

 (1)在内部类前加static的修饰符

 (2)静态内部类中可以声明static成员变量;非静态内部类中不可以;

 (3)静态内部类不可以使用外部类的非静态成员

 (4)创建静态内部类的对象不需要其外部类对象;

 创建非静态内部类形式

outer  o = new outer();

outer.inner i = o.new.inner();

静态内部类应用场景:(java集合类)像这种和外部类关系密切的,且不依赖外部类实例的,都可以使用静态内部类。

3.成员内部类:定义在类内部的非静态类,就是成员内部类。

public class Out {
    private static int a;
    private int b;
 
    public class Inner {
        public void print() {
            System.out.println(a);
            System.out.println(b);
        }
    }
}

外部类包含内部类

 例:

public class outer{//外部类

 //代码略

  public class inner{//内部类
   //代码略
  }

}

4.方法(局部)内部类:在类的局部定义的类叫做局部内部类(定义在方法中的类,就是局部类。);

局部内部类是嵌套在方法和作用于内的,对于这个类的使用主要是应用与解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类

参数中加final修饰符修饰,局部变量必须是final类型

 (1).在局部内部类里面都可以访问外部内部类的所有变量;

 (2).局部内部类访问访问方法中的局部变量的时候,局部变量必须声明final类型

例:

class outer{//外部类
  private String name;
  public void eat(final int i){//这里参数不加final,下面输出i会报错

    final int count = 0//这个是局部变量要final修饰,还要赋值

     class inner{//内部类
      
        public void innerEat(){//局部内部类
           system.out.printlc(name);
           system.out.printlc(i);//这个i之前要有final修饰
           system.out.printlc(count);//这个变量也要加final修饰,还要赋初值,否则会报错
         }
     }
 }

}

局部内部类应用场景:如果一个类只在某个方法中使用,则可以考虑使用局部类。

Java 继承


继承的概念

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

生活中的继承:

java 对象 对应数据库字段类型注解 java对象包含哪些信息_内部类_04

兔子和羊属于食草动物类,狮子和豹属于食肉动物类。

食草动物和食肉动物又是属于动物类。

所以继承需要符合的关系是:is-a,父类更通用,子类更具体。

虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。

还看不懂(这个讲的很容易让你理解什么是抽象类的真正意义):

           http://www.imooc.com/wiki/javalesson/abstractclass.html

抽象(分析与设计)abstract

(抽象类是为子类提供一个规范(类似制定法律),需要子类去继承,去遵守)

1.抽象类中的方法不一定是抽象方法;2.含有抽象方法的类一定是抽象类;

public abstract class dongwu{//抽象类动物,类似普通的类

  //定义抽象方法,这就是规范的具体形式(含有这个的方法一定是抽象类)

  public abstract void chifan(参数);//这个是吃饭的抽象方法,和普通方法差不多,就是没有“{}”大括号;



  //普通方法

    public abstract void chifan(参数){

      //代码

      system.out.print(“这个是普通方法”);

    };



}

继承抽象类extends:

1.一个类继承抽象类,就必须要重写该抽象类里的所有抽象方法(普通方法不一重写);

2.如果一个类没有重写抽象类里的抽象方法(不想重写),那么这个类要是抽象类(class前加abstract),这样才能继承抽象类;

//该dog类要继承动物抽象类,如果dog不是抽象类,那么需要重写dongwu抽象类里全部方法
public class dog extends dongwu {//不想重写就要在class前加上abstract


   //代码

   @Override //重写,用来检测是否重写成功,一定要重写
   public abstract void chifan();//这个是抽象类里的方法,需要重写,否则报错


   

    //普通方法,这个不需要重写

    public abstract void chifan(参数){

      //代码

      system.out.print(“这个是普通方法”);

    }







}

抽象:就是对事物的状态、行为进行概括、总结、描述。

抽象类总结规定

  • 1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
  • 2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  • 3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
  • 4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
  • 5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

接口(interface):

特殊的抽象类,比抽象类还要抽象,它是用来规定要做什么,但不规定怎么去做;

1.接口只有抽象方法,它比抽象类还要抽象,是彻彻底底的抽象;

2.接口只是抽象方法格常量的属性集合。

3.接口中只能包含抽象方法和常量,但不能有变量、初始化块、构造器等;

接口的定义:

public interface xuesheng{//xuesheng接口没有class

  int i=1;//变量,默认设置成共有的,相当于public static final i = 1;

  int banji=1201;//班级编号

  //定义抽象方法,只能定义抽象方法,普通方法不行

  void learn();//学习抽象方法

  void eat();//吃的抽象方法



}

实现接口:

 1.为接口中所有方法提供具体实现;

 2.必须遵守重写的所有规则 

   (1)子类的重写方法不能抛出更大异常;

 (2)子类重写方法不能有更小的访问范围

         如:父类:public void test();

                子类:public void test();--这是对的

                            protect void test();--这是错的,不能比public访问范围小

3.保持相同的返回类型  如:string、void返回都要一样

//一个学生1继承接口学生抽象类,可以多个,但加逗号分开,如还可以继承人得接口

public class xuesheng1 implementation xuesheng,people{

  @override //重写
  public void learn(){//重写接口的抽象方法,这是具体实现,就是正在学习(接口没有具体实现)
    system.out.print(“学生1在学习”);
  }

  @override //重写
  public void eat(){//重写接口的抽象方法,这是具体实现,就是正在吃饭(接口没有具体实现)
    system.out.print(“学生1在吃饭”);
  }

}

写个测试,看是否学生1继承接口成功,看看main函数输出;

public static void main(String[] arr){

  xuesheng1 stu = new student1();//new一个学生1的对象

  //访问学生1的方法,输出的就是具体的方法

  stu.learn();

  stu.eat();



  //访问接口的常量,在学生1没有这个常量哦,运行看看是否可以访问

   system.out.print(stu.banji);

  

}

接口的运用:

接口中的变量访问修饰符都是:public static final

接口中的方法访问修饰符都是:public abstract

people 是第2格接口,它继承两个接口;

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象类_05

调用对象和调用的接口有何区别:文字无法描述,请自己敲代码感受下;

java 对象 对应数据库字段类型注解 java对象包含哪些信息_java 对象 对应数据库字段类型注解_06

多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态是指同一操作(如吃的方法)作用于某一类对象(如动物类),可以有不同的解释,产生不同的执行结构;

例如:猫和狗都继承父类,父类都有吃的方法,但是猫和狗虽然都有吃的方法,但是猫吃鱼,狗吃骨头,吃的都不一样,这就是多态。

多态就是同一个接口,使用不同的实例而执行不同操作,如图所示(打印机就是多态的形式):

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象方法_07

多态性是对象多种表现形式的体现。

现实中,比如我们按下 F1 键这个动作:

  • 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
  • 如果当前在 Word 下弹出的就是 Word 帮助;
  • 在 Windows 下弹出的就是 Windows 帮助和支持。

同一个事件发生在不同的对象上会产生不同的结果。

多态存在的三个必要条件

  • 继承
  • 重写
  • 父类引用指向子类对

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象类_08

比如:

Parent p = new Child();

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

java 对象 对应数据库字段类型注解 java对象包含哪些信息_java 对象 对应数据库字段类型注解_09

以下是一个多态实例的演示,详细说明请看注释:

public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 对象调用 show 方法
      show(new Dog());  // 以 Dog 对象调用 show 方法
                
      Animal a = new Cat();  // 向上转型  ,动物有多种形态
      a.eat();               // 调用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下转型  
      c.work();        // 调用的是 Cat 的 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 {  //Animal动物是多态,类似打印机
    abstract void eat();  //动物都会吃
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  //这个动物吃的事鱼,类似打印机,一个打黑白
    }  
    public void work() {  
        System.out.println("抓老鼠");  //这个动物会抓老鼠
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  //这个动物吃的是骨头,类似打印机,一个打彩色
    }  
    public void work() {  
        System.out.println("看家");  //这个动物会看家
    }  
}

T执行以上程序,输出结果为:

吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠

向上转型:

 子类包含父类,父类是子类的一个子集。也就是子类转换为父类。

动物 A = new 狗()

java 对象 对应数据库字段类型注解 java对象包含哪些信息_java 对象 对应数据库字段类型注解_10

子类的方法有可能会丢失。

向下转型:

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象类_11

第一个很好理解,动物是父类,狗是子类,我们说狗是动物(向上转型),这个是对的。可我们能说动物是狗(向下转型)?这个不一定吧,需要判断,是才给转。

多态的实现方式

方式一:重写:

这个内容已经在上一章节详细讲过,就不再阐述,详细可访问:Java 重写(Override)与重载(Overload)

方式二:接口

  • 1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
  • 2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。

方式三:抽象类和抽象方法

详情请看 Java抽象类 章节。

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

重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。

在面向对象原则里,重写意味着可以重写任何现有方法。

方法的重写规则

  • 参数列表必须完全与被重写方法的相同;
  • 返回类型必须完全与被重写方法的返回类型相同;
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为final的方法不能被重写。
  • 声明为static的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。
  • 如果不能继承一个方法,则不能重写这个方法。

Super关键字的使用

当需要在子类中调用父类的被重写方法时,要使用super关键字。也就是先访问父类

重载(Overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最常用的地方就是构造器的重载。

到底什么是重载,我们来看看具体的实例。

举例:我们写个简单的计算方法

java 对象 对应数据库字段类型注解 java对象包含哪些信息_内部类_12

 我们调用:

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象类_13

 我们实例化很麻烦,简化下,加个:

java 对象 对应数据库字段类型注解 java对象包含哪些信息_内部类_14

 

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象方法_15

输出结构都为7

但是我传的参数不是int而是小数,就会报错,因为不通用。

java 对象 对应数据库字段类型注解 java对象包含哪些信息_内部类_16

 为了解决这个问题,我们用例重载的方法,改下计算方法

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象类_17

 我们进行调用,就不会报错了

java 对象 对应数据库字段类型注解 java对象包含哪些信息_抽象类_18

 如果我们传一个double和int混合,会不会报错?

java 对象 对应数据库字段类型注解 java对象包含哪些信息_内部类_19

 根据自动转型,这个不会报错。

总结,就是看参数类型来判断,所以重载的特点就是方法名一样,参数不同。

 

重载规则:

  • 被重载的方法必须改变参数列表(参数个数或类型不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。

重写与重载之间的区别

区别点

重载方法

重写方法

参数列表

必须修改

一定不能修改

返回类型

可以修改

一定不能修改

异常

可以修改

可以减少或删除,一定不能抛出新的或者更广的异常

访问

可以修改

一定不能做更严格的限制(可以降低限制)


重写和重载的总结

方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。

  • (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
  • (2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
  • (3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

java 对象 对应数据库字段类型注解 java对象包含哪些信息_java 对象 对应数据库字段类型注解_20

java 对象 对应数据库字段类型注解 java对象包含哪些信息_内部类_21

Java 封装


在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。

封装是将数据或对数据的操作(方法)绑定在类中的方法,保证数据不受外部代码的影响,可以想象成容器,其中有数据和对数据的操作,并且阻止外部代码随意进行访问,在面向对象语言中,把数据和方法放在一起形成了一个对象,对于对象中的数据和对数据操作通过成员代码进行操作和访问,如果不允许随便访问,设置为私有private,允许就设置为公有public。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。

封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。

适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

封装的优点

  • 1. 良好的封装能够减少耦合。
  • 2. 类内部的结构可以自由修改。
  • 3. 可以对成员变量进行更精确的控制。
  • 4. 隐藏信息,实现细节。
//封装:不想给别人看的进行封装,可以告诉的就公开

class Student{
	private String name;//private私有的,加这个只能在自己的类访问它,其他类不能访问,即不想告诉别人,隐藏起来
	private int age;
	private char gender;//
	//给gender提供一个共有的方法setGender,也就是可以公开的方法
	public void setGender(char gender){//命名规范,看到set开头就知道给成员属性做设置
		if(gender=='男'||gender=='女'){//增加控制用户乱输入,即只能输入男或女,不能输入其他内容
			this.gender=gender;
		}else{
			System.out.println("请输入正确的性别");//输入其他内容就提醒
		}
	}
	//不能直接输出了,需要定义一个方法
	public char getGender(){//命名规范,看到get开头取得意思
		return this.gender;//return gender;可以这么写,因为没有重名,加个this容易分清
	}
}
public class A6_12{
	public static void main(String[] args){
		Student one=new Student();
		//one.gender('f');这个是没有加private前可以直接传值,加private后还这么写就会报错
		one.setGender('男');
		System.out.println(one.getGender());
	}
}

包类:

JDK1.5以上才有的自动装箱和自动封箱,这个常用于泛型,详情请看泛型的知识;

这里的包类不是jar包,也不是工程包,而是涉及自动封装和自动拆装的基本概念,面试可能会问到int和integer的确保,你怎么回答?

int是基本数据类型;

integer是自动封装和拆箱的概念;

自动封装: integer i =10; 相当于 integer i = new integer(10);

自动拆箱:integer m = 10;

                    int n = m;

                 相当于:n = m.intValue(10);

1、Integer是int的包装类,int则是java的一种基本数据类型 
2、Integer变量必须实例化后才能使用,而int变量不需要 
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值 
4、Integer的默认值是null,int的默认值是0

类似int的自动封装和拆箱关键字对应integer的基本类型还有:

boolean、byte、short、long、float、double,它们对于的Boolean、Byte、Short、Long、Float、Double (记忆:首字母大写)

只有int和char对应的特殊,char对应的是Character
 

GUI:

这个涉及到界面和UI的制作和编写,网上的教程中也有讲到,最常用的是ATW和Swing,这些都是通过手动一行行敲代码敲出来的界面,这个知识不是非常重要,如今我们有可视化的工具,直接画出来就行;

ATW:是用于创建图形用户界面的一个工具包,有很多的API提供,如:Button按钮、Frame窗体;

Swing:就是在ATW上升级,多了些功能,他们的API前面都有大写的J,如:JButton,这就是Swing的;

这两个差不多,就是拥有的API不太相同;

在传统的使用方法中,程序员要做界面都是根据ATW提供的API去一行行代码新建,这里我就省略了这些API,如什么容器、窗体、事件等,感兴趣在网上搜索,

举个例子:你要新建一个窗体,窗体得有宽和高吧,还要设置窗体在屏幕哪个位置显示,需要坐标等;

Frame f = new Frame(“我的窗体”);//新建窗体

f.setSize(400,300);//设置宽和高,这个不是一下子就设置出合理的尺寸,400,300这个数据是调出来的

f.setLocation(300,200);//设置窗体显示在哪个位置,这个等获取电脑屏幕的坐标

以上的设置是不是很麻烦?我不喜欢这样,现在有辅助工具直接就像画画一样画出来,需要了解下简单的API,感兴趣的点击一下链接学习:

可以看看我的案例:

插件下载和安装使用的教程(效果展示):

详细的GUI教学:

异常

异常就是程序运行过程中出现的不正常现象,这一知识也不是必须的,大家了解即可,会使用就行,一般异常有提供API,有抓取特定的异常信息,当然肯定也可以自己定义异常,然后抓取并打印异常信息,反正我是很少用到,可以了解下!

异常的分类和概念(常见类型):

                                                                       Throwable(基类)

                  Error (错误)                                                                                           Exception(异常)

   VirtualMachineError(虚拟机错误)                                                      RuntimeException(运行时异常)

   OutOfMemoryError(内存溢出错误)                                                 NullPointerException(空指针异常)

   StackOverflowError(栈溢出错误)                                                     NumberFormatException(数字格式异常)

   ..................... 等等                                                                                  ArrayIndexOutOfBoundsException(数组越界异常)

                                                                                                                      ArithmeticException(运算异常)

                                                                                                                                          ......等等

Throwable:这个是所有异常的基类(父类),它有两个子类:Exception & Error

  Error(错误):它是java运行时内部错误以及内部资源耗尽。很难恢复,不期望用户来处理,这种就比较严重了,属于错误,不是异常;

Error几种场景异常:

VirtualMachineError(虚拟机错误):

OutOfMemoryError(内存溢出错误):内存泄露导致,内存不足、内存占用过大引起;

StackOverflowError(栈溢出错误)  :

  Exception(异常):表示应用程序错误,这个是所有的异常,异常有好多种,看看是哪些异常;

Exception几种常见的异常:

NumberFormatException(数字格式异常):这个是属于格式错误引起的,比如定义一个 int a;这个a必须是整数,如果你输入的是字母,那么就会报异常;

ArrayIndexOutOfBoundsException(数组越界异常):这个也好理解,一个数组,你定义arr[3],然而你却使用超过它的arr[4],这就越界了。

....等等不举例了,可以查查API,若是实在太懒,那就统一Exception的所有异常;

异常链:指两个以上不同的异常出现在同一个程序中;

异常的使用:

try :把可能发生异常的代码包起来,当发生异常抛出,try不能单独使用,一般和catch配合使用,还可以和final配合;

catch:捕获异常,并处理

finally:不管有没有异常,都会执行;

            我们有这种操作,打开文件--修改文件--保存--关闭文件,但是中间一步出问题了,如文件被删除了,这肯定会发生异常,那么就不会关闭文件,文件就一直开着了。所以我们会用到finally,不管中间发生了什么,文件打开了就要关闭操作;

           所以finally用于需要收尾,如上文件异常无法关闭,这个可以用这个来关闭,无论发生什么,我都关闭文件,释放内存;        

例子:

try{ //把可能发生的异常的代码包起来,有异常就不会执行



  int a =5;

  system.out.print(a/0); //被除数为0,会发生异常





} catch(Exception e){//捕获到异常,并处理;Exception 不管什么异常都捕获



  system.out.print(“被除数不能为0”);//异常栈,找出异常错在哪里,输出提示告诉用户



} finally{//不管有没有异常,都会执行;



  //就是用retrun都不能阻止它执行,除非暴力点用system.exit(0);语句,这个相当于关机了,这样final才不执行;



  system.out.print(“这句话总会执行,不管上面的有没有异常”);



}

 catch的异常处理,它可以多处理,代码例子来说明清楚点:

有点类似switch循环那种,满足哪个输出哪个,这个是满足哪个异常条件就捕获哪个信息,并输出相对应的提示

/*哪个捕获的信息就输出哪个信息,只输出其中一个,而不是全部都会输出*/
try{

//这里是可能触发异常的代码,主要关注catch,所以略!



}catch(NumberFormatException e){//这个是数字格式异常类型,发生数字格式异常时就执行这句



   system.out.print(“发生了数字格式异常,请注意数字格式异常是否正确”);



}catch(RuntimeException e){//运行时异常类似,运行时出现异常时才执行这句



   system.out.print(“运行时异常,请检查运行时出现了什么异常”);



}catch(Exception e){//若是以上的都没有,也不知道什么类型的异常,就加上这个全能的异常捕获,这个虽是什么异常都捕获,但是如果上面都已经捕获了,这个就不能在捕获了//所以这个Exception不能放在第一个,只能放在最后一个,否则其他的异常类似都毫无意义,切记!;



   system.out.print(“发生异常了,但不知道什么异常,请检查下”);



}

自定义异常:

这些异常捕获都是别人写好的方法,那我们能不能定义我们自己的异常方法呢,按照我们自定义规则去捕获来提示我们自己想要的异常信息,异常都是定义好的规则,让别人去调用,如try/catch捕获,这是集成了Throwable基类(别人写好的异常)。

我们自己要新建异常就要继承Exception,自定义好的规则让别人调用,创建自定义格式如下:

修饰符 class 类名 extends Exception{

//里面自定义的异常规则代码

}

例子:

//自定义一个自己的异常,叫MyException

class MyException extends Exception{ //修饰符要不要都可以





   public MyException(){

   //一个构造函数方法,补习下,用于初始化,名字于类名相同,无void和retrun





   }

   

   public MyException(String msg){//有参数的构造方法

     super(msg);//访问父类



   }





}

我们自己定义的异常规则已经写好了,这就等待别人去使用了,我们写个测试方法去调用试试:

//当别人调用自己的异常类

public static void main(String[] args){



 MyeException me = new MyException("自己的异常类");//有参的构造方法

 system.out.print(me.getMessage());//调用我们自己定义的异常类



 system.out.print(me.toString);//这个会打印出哪个包,哪个类的信息,如:bao.MyMyException





}

输出:

自己的异常类

bao.MyMyException 自己的异常类

好了,我们自定义的场景也有,比如写人的年龄,年龄你不可能写10000岁吧,那就不是人了,对吧!

自己的异常类一般用于throw,让别人调用。

我们自己可以定义:10~18岁小孩,18~30青年,30~60中年,60~120岁老人。大于120岁就抛出异常。

自定义一个异常:

static String agelevel(int age)throws IllegalAgeException{//下面用IllegalAgeException,这里就声明下,继续往外抛

  

   //10~18岁小孩,18~30青年,30~60中年,60~120岁老人,这就是用到if语句

   if(age>10&&age<=18){

      return "小孩";

   }

   else if(age>18&&age<=30){

      return "青年";

   }

   else if(age>30&&age<=60){

       return "中年";

   }

   else if(age>60&&age<=120){

       return "老人";

   }

   else{//大于120岁或者其他,都是异常了,这里我们就定义它--自定义

      //自定义的IllegalAgeException,手动抛出来的异常
      Throw new IllegalAgeException(“非法年龄!!!”);

   }  



 }

别人调用:

public static void main(String[] args){



  try{

     agelevel(1000);//agelevel的方法传入1000的值,调用输入值范围值外的,人不可能这么大

  }catch(IllegalAgeException e){//IllegalAgeException这个就是我们自己定义的异常

   

     e.prinStackTrace();//打印显示出来控制台,结果肯定是:非法的年龄!!!---自定义的



  }





}

根据例子你是否明白自定义异常的使用了吧!

手动引发异常:

Throw:这个是手动引发一个异常,手动抛出来的异常,必须捕获;

前面代码案例里也有手动抛出异常:Throw new IllegalAgeException;这就是手动抛出

格式:throw ,明显的异常,就要手动抛出。

public void test()Throws Exception{//这里可以声明异常,因为手动抛出异常,明显就是有异常

  //这个既然是手动抛出来的,肯定就是异常,既然是异常就要处理try/catch,不然就声明throws一下。
  throw new Exception(“这个是手动跑出来的”);


}

throw exception:参数exception表示要抛出的异常对象,该对象是throwable类的子类,而且只能是一个。

例子:

声明异常

Throws:这个是定义任何被调用方法的异常(声明异常)---只声明,不捕获;

               指一个方法不处理它所产生的异常,而是调用层次向上传递,谁调用这个方法,谁来处理;

格式:

//只是声明,没有处理,那么谁要调这个方法,那谁就处理

修饰符 class 方法名() throws 异常类型(如:RuntimeException(运行时异常)){



}

有这种场景,当程序员在写自定义异常的时候,懒得去捕获,所以谁要调用谁就去捕获,代码展示:

修饰符 class test() throws ArithmeticException){



  //写个方法,这个方法内容可能是发生异常,但是程序员懒得处理,如:



  system.out.print(1/0);//被除数不能为0



}

//好,当别人要调用这个test的方法的时候,test()没有throws声明异常,
//程序会报错,因为没有人去处理,当上面有throws声明后就没有异常

public static void main(String[] args){



  Test t = new Test();



 try{

   t.test();

   //调用,上面虽然抛出了Throws,但是没有处理,只是声明,所以我们自己要处理,用try/catsh

 }catch(ArithmeticException e){//上面没有捕获,谁调用就自己捕获



    system.out.print(e.getMessage);//打印出捕获信息



 }

 system.out.print(“main方法结束”);

}

所以Throws只是声明,没有处理,别人调用会出错,不执行后面的代码。

虽然懒就不用太懒,不可以把活都干了(自己捕获try/catch),就算你不捕获不处理至少给别人说一声啊(声明异常),写着多了,良心发现,就自己处理异常,这样别人直接调用就没有问题。

如:

修饰符 class test() throws ArithmeticException){



  //写个方法,这个方法内容可能是发生异常,但是程序员懒得处理,如:



  system.out.print(1/0);//被除数不能为0



}



修饰符 class test1() throws ArithmeticException){



  //一样懒得处理,就告诉人家(声明异常)



  system.out.print(1/0);



}

修饰符 class test2() throws ArithmeticException){



  //还是懒



  system.out.print(1/0);



}



/**这里不只声明,还处理**/



修饰符 class test3() throws ArithmeticException){



  //写到这里突然良心发现,不处理不行,让别人调用方便点,得了,这活我干了



 try{

  system.out.print(1/0);

 }catch(ArithmeticException){

   system.out.print(e.getMessage);

 }



}





//当我们调用test4()时,因为test4()已经帮我们处理了,调用时我们就不需要处理了



public static void main(String[] args){



  Test t = new Test4();



   t.test4();

   

 system.out.print(“main方法结束”);

}

据代码可知,程序员要是勤快点,调用的就方便,就算你懒不想处理,至少要声明下告诉人家,这是必不可少。

看完还不懂面向对象?那只能建议你到网站详细学习咯!还不行最好找个视频看看,0基础推荐51自学网,有基础的能看的下文字和书籍的推荐以下网址。

---------------------------------持续更新中,不明白的给我留言·······················