java面向对象


一、面向对象概念

将功能封装进对象,强调具备了功能的对象,该对象中的功能被调用。

注意:C都是标准的“面向过程”的语言,“面向对象”是基于“面向过程”的!

二、类和对象的关系

1、概念:

类就是对现实生活中事物属性的具体描述,对象就是这类事物中实际存在的个体,具体到了个体。

 

2、组成:

一个类中包含两种内容:“成员变量”和“成员方法”

比方说:Car car=new Car();

car可以说成临时性变量,CAR()是对象,car指向的是CAR对象,car也被称为“句柄”,car就是一个类类型的变量。

 

3、“类”注意:

只要是使用关键字new,就是在内存中创建了一个新的对象。

 

4、对象的特点:

用于封装数据,数据包含这属性和行为动作。

Object是所有类的“上帝”!默认情况下,所有的类的“父类”都是Object。

 

5、内部类:

当内部类被static修饰的时候,只能直接访问外部类中的static成员,出现访问权限。

在外部其他类中,如何直接访问static内部类的非静态成员呢:new Outer().new Inner();
在外部其他类中,如何直接访问static内部类的静态成员呢:new Outer.Inner().function();

 

6、“类”注意:
(1)、当内部类定义了静态成员,该内部类必须是static类型的!!!!!
(2)、定义在方法中的类也称为内部类!
(3)、一个平常的类一般是不用private进行修饰的,如果修饰就没有任何意义了,但是一个内部类可以被private修饰。(可能会作为一道面试题)

如果在这个方法中定义了一个"变量",在这个方法中的类如果想要使用这个“变量”的话,并在自己的方法中“输出“这个变量,那么这个变量必须被修饰成final类型的变量,也就是成为”常量“!

 

7、匿名内部类:
(1)、匿名内部类说白了就是“内部类的简写格式”,所以要简写的话,必须实现下面的内容。
(2)、定义匿名内部类的前提:内部类必须是“继承一个类”或者“执行一个接口”,这样才可以创建匿名内部类。
(3)、匿名内部类的格式:new “父类”或者是“接口”( ){ 定义子类的内容 }.方法

其实匿名内部类就是一个匿名的子类对象,而且这个对象有点胖,内容有点多,自己可以理解成“带内容的对象”。

 

8、不使用匿名内部类来实现抽象方法:

abstract class Person {
    public abstract void eat();
}
 
class Child extends Person {
    public void eat() { //进行覆盖操作
        System.out.println("eat something");
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Child();
        p.eat();
    }
}

 

9、使用了匿名内部类来实现抽象方法:

 

abstract class Person{
 public abstract void eat();
}

public class Demo{
 public static void main(String[] args){
  Person p=new Person(){
   public void eat(){ //进行覆盖操作
    System.out.println("eat something");
   }
  };
  p.eat();
 }
}

或者:

abstract class Person{
 public abstract void eat();
}


public class Demo{
 public static void main(String[] args){
  new Person(){
   public void eat(){ //进行覆盖操作
    System.out.println("eat something");
   }
  }.eat();
 }
}

注意:匿名内部类中定义的方法最好不要超过3个!

三、主函数的功能

1、概念:

主函数就是一个入口,最终目的是用来调用同一包中其它类创建的对象,从而达到功能动作的实现。

2、编程习惯:

要养成一个良好的编程习惯,将需要被调用的方法和被使用的属性封装到类中,通过类创建对象被主函数进行调用使用。

3、注意:

自己也可以在一个普通的类中创建主函数的,从而让这个类成为一个独立的功能来运行。

四、匿名对象

1、概念:

“匿名对象”就是没有名字的对象。

2、举例:

如果说Test t=new Test();是一个有名字的对象的话,那么:new Test();就是一个匿名对象,省略了t这个引用。

3、匿名对象的作用:

通常编程的时候,这个匿名对象是没有什么用处的,但是有的时候我们可以用匿名对象简化代码行数,从而提高代码的性能,执行效率,这是在以后为成为高手所做的十分必要的课程。

五、属性private访问权限

1、注意:

封装不是私有!私有仅仅是封装的一种表现形式。在开发的时候,一定要为定义的每一个变量设置访问权限,比方说用private修饰的变量,就是为了防止别人私自对自己的程序属性进行篡改,从而保证了程序的安全性。之所以对外提供访问方式,就是因为可以在访问的过程中加入逻辑判断语句,然后对访问的数据进行判断操作,从而提高了代码的健壮性。

2、封装的原则是:
(1)、将不需要对外提供的内容进行隐藏。
(2)、把属性都隐藏,也就是将类中的变量之类的进行隐藏,只提供公共方法对其访问。

六、成员变量和局部变量的区别

1、作用范围
成员变量:作用于整个类中。
局部变量:作用于函数中。

2、存在位置
成员变量:在堆内存中,因为对象已经存在了,所以在内存中存在。
局部变量:存在于栈内存中。

3、初始化
成员变量:因为存在于堆内存中,所以会有默认的初始化值,所以不用初始化也可以参与运算。
局部变量:因为存在于栈内存中,所以没有默认的初始化值,所以必须进行初始化才可以运算,否则不参与运算。

4、注意:

变量是不存在覆盖的,是随着类走的,所以成员变量看左边!子类或者父类输出覆盖的方法的时候,输出的是相同的内容!因为是覆盖!

5、下面的例子将会说明问题:

 

class Fu{
 int x=4;
 void show(){
  System.out.println("showFu");
 }
}

class Zi extends Fu{
 int x=6;
 void show(){
  System.out.println("showZi");
 }
}

class Zhu{
 public static void main(String[] args){
  Fu f=new Zi(); //变量不存在覆盖,随着类走,所以成员变量看左边
  Zi z=new Zi();
  System.out.println(f.x);
  System.out.println(z.x);
  z.show();
 }
}

输出的结果将是:4,6,showZi
说明了变量是不会被改编的,但是方法会被覆盖。

 

七、set和get

set和get的一个重要作用就是对前面已经赋值的特定内容进行修改,所以set和get一般是成对的出现的。对一个数值进行了修改,然后想对这个已经修改的内容进行输出的话,可以用get方法对其进行输出操作,相当的不赖。

八、构造函数(方法)

1、构造函数概念:

就是和类名相同的一个方法(函数)。给一个类创建了构造函数之后,如果其它函数中想调用这个构造函数的话,只需要建立这个类的对象就可以直接对这个构造函数进行调用。

 

2、构造函数的作用:

对对象进行初始化操作。

注意:

对象一旦建立,就会调用对应的构造函数!如果类中没有构造函数,那系统就会自动为相对应的类创建一个没有任何参数的构造函数,比方说:Person(){},这样方便该类进行初始化!如果类中自定义了构造函数之后,默认的构造函数是没有的。

 

3、构造函数和一般函数的不同之处:
(1)、构造方法在对象一创建的时候就运行,给对象进行初始化操作,而一般的方法是对象被调用的时候才运行,是给对象添加对象具备的功能而已。
(2)、还有一个对象建立的话,构造方法只运行一次,但是一般方法可以通过对象的多次调用而运行。

一个类默认的构造函数的权限和所属类的权限是一样的,如果类被public修饰的话,那么默认的构造函数也被public所修饰,如果类没有被public修饰的话,那么默认的构造函数,也是没有public修饰的,并且默认构造函数的权限是随着类的变化而发生变化。

 

4、构造函数的继承:

当对子类对象进行初始化的时候,不仅子类中的构造函数会执行,父类的构造函数也会执行。那是因为子类的构造函数的默认第一行有一条隐式的语句super()。super()的作用就是访问父类中“空参数“的构造函数,并且子类中所有的构造函数默认第一行都是super()。

 

5、为什么子类一定要访问父类中的构造函数呢?
父类中的数据子类可以直接获取,所以子类对象在建立的时候,需要看看父类是如何对这些数据进行初始化的,如果要访问父类中指定的构造函数(也就是非空构造函数),可以通过手动定义super语句的方法来指定。相当地方便哈。

 

6、注意:

super一定是定义在子类构造函数的第一行的。为了检查父类中构造函数中的内容是否影响自己构造函数中的内容。

 

7、结论:

子类的所有的构造函数,默认情况下都回访问父类中空参数的构造函数,因为子类中每一个构造函数内的第一行都有一句隐式的super()语句。当父类中没有空参数的构造函数时,子类必须手动通过super语句来指定要访问父类中的构造函数。当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,子类中至少会有一个构造函数会访问父类中的构造函数。

九、“构造代码块”和“静态代码块”

1、构造代码块的格式:
{
 构造代码块内容;
}

注意:构造代码块的优先级高于构造函数!所以主函数中对应类的对象一旦建立的话,就会运行!

 


2、构造代码块和构造函数的区别:

(1)、构造代码块给所有的对象进行统一初始化。
(2)、构造函数只给对应的对象进行初始化。

构造代码块中定义的是不同的对象共性的初始化的内容,可以将他们提取出来放入构造代码块中,这样增强了代码的健壮性和简化代码量,每一次对象的运行都会调用构造代码块,所以构造代码块的运行次数视对象调用的次数而定。

 

3、静态代码块格式:
static{
 静态代码块中的内容。
}

静态代码块作用:就是给相应的类进行初始化。

注意:static修饰的静态代码块绝对会被执行到,这是必须的!并且必须被执行一次的,这也是必须的!

 

4、类中各种方法执行的优先级:

静态代码块>构造代码块>构造方法>定义的方法(一般方法)

 

下面的小程式说明问题:

class Demo{
 Demo(){
  System.out.println("我是构造函数");
 }
 {
  System.out.println("我是构造代码块");
 }
 static{
  System.out.println("我是静态代码块");
 }
}
public class PriorityDemo {
 public static void main(String[] args) {
  new Demo();
  System.out.println("我是主函数");
 }
}

输出结果是:
我是静态代码块
我是构造代码块
我是构造函数
我是主函数

说明优先级问题得到印证。

十、this关键字

1、this关键字概念:

当一个有参数的方法(函数)中的参数名字(也就是局部变量)和我们先开始定义的成员变量的名字(也就是全局变量)相同的时候,执行这个方法(函数)的时候就会出现识别名字出错的情况,所以我们这里使用this关键字可以提醒系统区分“成员变量”和“局部变量”重名的情况。

String name;
Person(String name){
 this.name=name;
}
上面构造函数中,如果我们用name=name的话,系统无法识别到底这个name是上面定义的“成员变量”得name,还是下面方法(函数)中参数的name,所以我们可以使用this关键字来区别这两个name,this代表的是本方法中的对象,也就是说String中的name就是this.name=name;中后面的那个name。

 

2、注意:

this就是一个对象的引用很多时候我们都会省略this关键字,因为很多时候并不需要。就像我是“河南师范大学名字叫做XXX的一名学生”一样,如果我的同学在同一个学校中这样叫我“哎,河南师范大学的XXX”这样听着很是别扭,直接叫我“XXX”就可以了,所以this就是“这个”的意思了!

this调用构造方法:this关键字不仅可以用来做对象的引用,还可以作为构造方法的引用。比方说:在一个类中,有多个名字相同的构造方法,但是这些方法中有的功能重复了很多,也就是说说一个方法中包含了另一个方法的一些功能,使用this调用方法的话就不用非得将已经有了的功能在写一遍,我们只需要调用方法即可。

A(int age){
 this.name=name;
}

A(String name,int age){
 this(age); //这里直接调用的是上面构造方法中的一个参数操作,简化代码
 this.name=name;
}

3、注意:

构造函数之间的调用必须要使用的是this关键字,没有省略一说,this关键字在构造函数中必须定义在函数中的第一行!因为要初始化!this调用中不允许出现死循环类型的调用步骤!会出现意想不到的情况!

 

4、this和super的区别:
this关键字一般被使用在本类中的变量调用,但是如果子类和父类中的变量名字相同的话,在主函数中调用的时候,到底使用的是子类中的变量还是父类中的变量呢?当然使用的是子类中的变量了,因为调用的时候,前面省略的是this关键字,如果想调用父类中的变量的话,可以使用super关键字。如果一个子类中使用了super(),那么就是使用了父类中的空参数的构造函数(方法)!!!

十一、static修饰符

1、static概念:

顾名思义,“静态”的意思,static是一个修饰符,只能用于修饰成员(成员变量+方法)。

 

2、什么时候使用静态:

当对象中出现共享数据的时候,该数据一般被静态所修饰!

 

3、注意:

对象中的特有数据要定义成非静态存在于堆内存中!当方法内部没有访问到“非”静态的数据时(也就是“对象的特有数据”),那么该方法可以被修饰成静态的。堆内存中的静态方法重来没有访问过啊!

如果用new创建了一个对象的话,将会在内存中开辟一段空间。但是如果一个成员变量or方法被修饰成static的话,在内存中将会发生变化,首先这个变量or方法将会被使用的东西所共享,不会反复开辟内存空间,从而节省了内存空间。

 

4、static的利与弊:

利:对于对象的共享数据进行单独的处理,从而节省了空间,没有必要每一个对象都得存储一份重复的内容(参数or方法)。
弊:生命周期过长、访问的局限性(静态只可以访问静态)。

static修饰的方法(函数)可以直接被“类名”调用,“非静态”前面一般省略的事this关键字,所以总结一句话:“静态”前面跟到是“类名”,静态方法中是没有this的!“非静态”前面跟的是“this”,一般省略的也是this。所以,“非静态”前面非要说省略的话,省略的是   "this.",“静态”前面要是省略的话,省略的是   "类名."。

 

5、static的特点:
(1)、随着类的加载而加载:静态会随着类的消失而消失。因为类才能创建对象,一定意义上说明静态修饰的东西的寿命比对象的寿命要长!
(2)、优先于对象存在:因为static修饰的东西是随着类的创建而创建的,所以对象存在于“静态”的后面。并且静态优先于主函数执行!
(3)、被所有的对象所共享:不用说了,这就是static修饰的东西存在的意义。
(4)、可以直接被类名调用:这是一种规定,带来的好处就是简化代码量。

(5)、static进内存是没有创建对象的。

十二、main函数

主函数中相当重要的一句话是:public static void main(String[] args){}

自己知道字符串可以转换成各种类型的数据,从而体现了字符串的强大之处,mian函数中包含了元素是String类型的数组,args是arguments的简写,就是“参数”的意思,多个”参数“的意思,所以后面加一个s。

主函数的组成:

1、public:代表着该函数的访问的权限是最大的
2、static:代表着主函数随着类的加载就已经存在了
3、void:主函数没有具体的返回值,因为是void类型的
4、main:不是一个关键字,但是个特殊的单词,可以被jvm识别,换任何一种写法都是不行的!
5、(String[] args):函数的参数,这里的类型是一个数组类型,该数组中的元素是一个字符串,字符串类型的数组。
6、主函数是固定格式的,这样才可被jvm识别出来使用

面试注意:一堆类中有一个主函数,用来调用这些类,主函数是一个程序的入口,从而让程序得到执行,一般情况下,主函数的作用都是用来调用别的类中的方法的,面试的时候,可能会出一些比较反常的内容。

十三、编程思想

1、一般的编程思想:

在同一个包中建立一个类,这个是功能类,里面封装了各种各样的函数(方法)用来实现各种各样的功能,再写一个主函数文件,用来调用我们先前写的工具类(也可以称为功能类)可以通过主函数内调用方法,从而实现各种各样功能的实现。

 

2、快捷的编程思想:

自己发现如果定义了一个工具类,在主函数中调用这个工具类的时候,还得创建对象什么的,这是比较麻烦的事情,所以为了简化代码量,一般将“工具类”里面的方法(函数)全部定义成static静态方法(函数),然后就不用在主函数中创建对象调用方法(函数)了,直接用类名调用静态(方法)函数就可以了。

但是如果功能类中的方法全部被修饰成了静态static的话,设计的功能类还是可以被其它的主函数通过创建对象的方法调用的,从而产生不是特别安全的一个问题。所以为了程序的严谨性,我们可以强制让该类不能创建对象,所以可以使用private这个关键字“私有化”该类。

 

3、注意:

每一个类中都有系统默认的构造方法,但是构造方法中没有任何的内容,我们为了不让别人通过创建对象的方式调用构造方法,可以直接将一个类中的构造方法私有化。

十四、单例设计

1、“唯一性”概念:

就是说在“堆”内存中,只允许一个类创建的一个对象的存在,然后在主函数(主方法)中创建N多对象对同一个“堆”内存中的对象进行操作。

 

2、“唯一性”创建的步骤:
第1步:为了防止别人为了创建对象使用“构造函数”,将构造函数private私有化。
第2步:在类中创建一个本类的对象,一般都“私有化”以及“静态”。
第3步:提供一个可以获得该对象的方法,用于返回前面“本类”中创建的对象的名字。

 

3、什么情况下使用“类的唯一性”?
(1)、对类属性的描述还是那个样子,该怎样就怎样。
(2)、当需要对该事物的对象保证在内存中唯一的时候,就使用以上的三个步骤即可。

为了使创建的对象“唯一”,有了“单例设计”,但是“单例设计模式”有两种:“饿汉式”、“懒汉式”。

 

4、注意:

在开发的过程中,一般用的是“饿汉式”,方便,效率高。在面试的过程中,一般使用的是“懒汉式”,麻烦,有技术含量。为什么呢?因为“饿汉式”比较简单,效率比较高,代码少。“懒汉式”需要判断的东西比较多,一般判断次数少的时候,前两次也至少需要判断“两次”,所以效率上来说有点低。

两种“单例设计”简写:

5、饿汉式:(上来就开辟内存,可以理解成上来就“吃内存”)

private Single(){} //私有化构造函数,防止别人创建对象
private static Single s=new Single(); //在本类中创建对象,用于下面的返回中
public static Single getInstance(){ //创建一个方法,用来返回对象创建的s
 return s;
}

6、懒汉式:(可以理解成“吃饱喝足了”,别人再“端上来东西”的时候,“懒汉“要判断一下,自己吃不吃,也就是判断一下”需不需要占用内存“)

private Single(){}
private static Single s=null; //先初始化为空
public static Single getInstance(){
 if(s!=null){ //先判断一下后面的对象是不是为空,空则进行,不空则退出。
  synchronized(Single.class){ //synchronized的作用是”上锁“,防止过多的创建对象,“同步函数“中会讲到
   if(s==null)  //如果为空,就创建一个新的对象,如果不为空,就退出。
    s=new Single();
  }
 }
 return s;
}

 

7、具体代码示例:

class Cyc{
 private static String name;//因为下面使用该变量的方法是“静态”的,所以这里的变量都是“静态”修饰的,按照编程规范,变量最好“私有化”
 private static int age;
 
 private Cyc(){}//构造函数私有化,防止别人创建对象调用构造方法,所以将“构造函数”干掉!
 private static Cyc cyc=new Cyc();//在“本类”中创建一个对象,目的是让下面的方法进行返回
 public static Cycf1(){
  return cyc;//返回之后定位到“本类”然后就可以执行类中的其他方法了
 }
 
 public void setName(String name){
  this.name=name;
 }
 public String getName(){
  return name;
 }
 public static void setAge(int age){
  age=age;
 }
 public int getAge(){
  return age;
 }
 
 public static void f(){//修饰成“静态”的可以使用“类名”调用方法
  System.out.println("name="+name+"age="+age);
 }
 
}
public class DuiXiangDeWeiYiXing {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Cyc c1=Cyc.f1();//类名只能调用“静态”修饰的方法
  Cyc c2=Cyc.f1();
  /*
   * 这样就可以实现多个“事物”调用“同一个事物”
   * */
  
 }

}

十五、方法区

注意:创建的对象是在“堆”中开辟了一部分空间,变量是在“栈”中开辟了一个“临时”的空间,那么用static修饰的成员变量or方法因为自己是共享的内容,需要存储到什么地方呢?方法全部放在了“方法区”内。就像两个人都是住在“中国”一样,所以“国家”这个属性可以被修饰成static,成为一个被共享的地方,这个地方被称为“方法区”or“共享区”or“数据区”,它是不同于“栈”和“堆”的一个地方,自己可以先理解成处于两者之间的一个地方。

十六、实例变量和类变量的区别

1、存放位置
类变量随着类的加载而存在于方法区中。(重点!)
实例变量随着对象的建立而存在于堆内存中。
2、生存时间
类变量生命周期最长,因为它是随着类的消失而消失,只要类创建,它就存在。
实例变量生命周期随着对象的消失而消失,而对象是在类后面创建的,所以综合看来还是类变量活得长,实例变量活的短点。

十七、对象的初始化过程

Person p=new Person("zhangsan",31);

这句话的执行过程:
1、new关键字用到了Person.class文件,所以会先找到Person.class文件并且加载到内存中去。
2、到了内存中,如果类中有静态代码块,就执行,如果没有,不执行,给Person.class类进行初始化。
3、在堆内存中开辟空间,分配内存地址。
4、在堆内存中建立对象的特有属性,并进行默认的初始化,比方说,int类型的为0,String类型的为null。
5、如果属性进行了重新的初始化,那么就进行“显式初始化”,重新进行初始化。
6、如果有“构造代码块”的话,对对象进行“构造代码块”的初始化。
7、对对象进行对应的构造函数的初始化。(也就是说:用哪个函数初始化哪个函数)
8、p是变量,也是引用,是对象Person创建的变量,最后一步是将内存地址交付给栈内存中的p变量。

十八、函数(方法)的重写和重载

1、重写:

就是将多个名字、类型、参数完全相同的函数[方法]中的内容重写一下,进行覆盖操作。

2、重载:

就是多个名字一样的方法[函数],但是”参数以及参数类型”或者是“方法[函数]类型不一样”,在主函数中调用某个方法[函数]的时候,只需要将自己想要的参数类型或者参数个数相对应就可以进行调用。

3、总结:
重写:子父类的方法要一模一样才可以。
重载:只看同名函数[方法]的参数列表。

十九、final关键字

1、final的作用:
(1)、可以修饰类,变量,函数(方法)。
(2)、用final修饰的类不可以被继承!利用这一点,可以避免被子类继承。
(3)、同样,被final修饰的方法(函数)同样不能被复写。
(4)、被final修饰的变量是一个常量了,不能被修改,只能赋值一次,即可以修饰成员变量,亦可修饰局部变量。

2、常量:

当在描述事物的时候,一些数据的出现是固定的,为了增强其阅读性,都给这些值起个名字,方便阅读,而这个值不需要改变,可以加上final修饰,作为一个常量。

3、常量格式:

所有的字母都必须大写,如果由多个单词组成的话,单词间通过“_”链接。final int m=0;

4、注意:

内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。

二十、abstract抽象类&抽象方法

1、什么是抽象:

抽象说白了就是“看不懂!”,将一个原来很多个子类中通有的某个内容抽取出来,放在父类当中,用到的时候直接调用就可以了。

2、什么时候用抽象:

当多个类中出现同样的功能,但是功能主体是不同的,就要进行复写了,所以这个时候用抽象修饰!抽象方法(函数)是不能定义方法体的!可以向上抽取到父类中,这时,只抽取功能的定义,也就是“名字”,不能抽取功能的主体,因为主体是用来被复写的。

3、抽象特点:
(1)、抽象的方法(函数)一定在抽象类中!
(2)、只要是抽象的都必须用abstract修饰,这是必须的哈!
(3)、抽象的类不能new创建对象!因为抽象方法(函数)没有方法体,调用无意义!
(4)、如果抽象类中的方法要被使用的时候,必须由子类复写所有的抽象方法之后,建立子类的对象进行调用。

4、注意:

如果子类仅仅覆盖了部分的抽象方法的话,那么该子类还是一个抽象类,eclipse会提示出错,不能让你进行编译的!

二十一、接口interface

注意:
1、接口和抽象类非常的相似,接口中的方法也都是没有方法体的!
2、接口中的成员都是public修饰的。
3、接口是不可以创建对象的,原因和抽象类abstract一样,因为里面的方法都是抽象的,没有方法体,创建对象调用无意义!
4、如果需要被子类实现的话,子类对接口中的抽象方法全都覆盖后,子类才可以实例化,否则子类就是一个抽象类。(这一点和抽象类中的实例化是一模一样的!)

 

接口中的特点:
1、接口中常见的内容:final修饰的常量,抽象方法。
2、接口中的成员都是固定修饰符的:常量:public static final。方法:public abstract。
3、接口是对外暴露的。
4、接口是程序的功能扩展。
5、接口可以用来多实现。
6、类和接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
7、接口与接口之间可以有继承关系。

二十二、继承

1、多继承的安全隐患:

当多个父类中定义了相同的功能的哈。当功能内容不同的话,子类对象不确定要运行哪一个。但是java保留这种机制,并用另一种体现形式来完成表示。

2、注意:

实际上,java是支持多继承的,接口支持多继承,也就是一种继承体制。

3、如何使用一个继承中的功能呢?

想要使用体系,首先查阅体系父类的描述,因为父类中定义的是该体系中共性的功能。
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系基本可以使用了。


4、那么在具体调用时,要创建子类的对象,为什么呢?

一是因为有可能父类不能创建对象,
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的,

简单一句话:查阅父类功能,创建子类对象使用功能

二十三、多态

平常声明对象:猫 x=new 猫();
多态声明对象:动物 x=new 猫(); 
1、多态的表现:父类的引用指向了自己的子类对象,也就是说父类的引用也可以接受自己的子类对象。
2、多态的前提:必须是类与类之间的关系,要么继承,要么实现,子类与子类之间也需要有关系,通常还有一个前提:存在覆盖。
3、多态的好处:多态的出现大大提高了程序的扩展性。
4、多态的弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员。

二十三、instanceof运算符

instanceof是一个双目运算符,通过一个例子进行讲解:a instanceof Cat,左面的操作元是一个对象,右面的是一个类,当左面的对象是右面的类创建的对象时,该运算结果是true,否则false。

二十四、throw和throws的区别

throw是在函数(方法)内出现的,但是throws是在函数(方法)前面出现的。

throws后面跟的是异常类,并且可以跟多个,中间用逗号隔开即可。
throw后面跟的是异常类创建的对象。

二十五、异常

1、异常:

是对问题的描述,将问题进行对象的封装。

2、异常的体系:
 Throwable
    |--Error
        |--Exception
            |--RuntimeException

3、特点:

异常体系中,所有的类以及建立的对象都具备可抛性。意思就是:可以被throw和throws关键字进行操作。只有异常体系体系具有这个特点。

在抛出异常的时候,经常会用到一句话:exception e,如果抛出的是“数学类”的异常,实际上这一句话的意思是:用exception创建了一个AritchmeticException()异常对象,全句话的意思就是:Exception e=new AritchmeticException();但是在程序里面后面这句话是不予以显示的。

4、常用的异常输出语句有:

printStackTrace();这个语句输出的是异常的名称、异常的信息、异常出现的位置。

5、注意:

实际上jvm默认的异常处理机制,就是在调用printStackTrace这个异常方法,用来打印异常的堆栈的跟踪信息。

6、异常由来:

问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象。

7、异常可以分为两种:
(1)、严重的:Java通过error类进行描述,对于error一般不编写针对性的代码对其进行处理。
(2)、非严重的:java通过exception类进行描述,对于exception可以使用针对性的处理方式进行处理。

8、注意:

无论error或者是exception都具有一些共性的内容。比如,不正常情况的信息,引发的原因等。throwable是异常的“超类”,也就是“父类”。

9、throw和throws的用法:
(1)、throw定义在函数内,用于抛出异常对象。
(2)、throws定义在函数上,由于抛出异常类,可以抛出多个异常类,中间用逗号隔开。

当函数内容有throw抛出异常对象,并没有进行try处理的话,就必须要在函数上声明,否则编译失败!(这是常识嘛)
注意:RuntimeException除外,也就是说,函数内如果抛出的RuntimeException异常,函数上可以不用声明!

 

10、异常有两种:
(1)、编译的时候检测出异常:该异常在编译的时候,如果没有处理(没有抛出异常也没有try),编译失败。该异常被标识,代表可以被处理。
(2)、运行的时候检测出异常:(编译的时候不检测)在编译的时候,不需要处理,编译器不检查,该异常的发生,建议不处理,让程序停止,需要对代码进行修正。

 

11、异常处理语句:
try{
 需要被检测的代码,看看是不是错误。
}
catch(前面自定义异常类“继承”的“系统异常类”创建的“引用“){
 检测出异常需要的处理方式。
}
finally{
 一定会执行到的代码
}

 

12、finally内容:
(1)、finally中定义的通常是关闭资源代码,因为资源必须释放的。
(2)、finally只有一种情况不会被执行到的,就是执行到System.exit(0);的时候,finally不会被执行的!!!!!

 

13、注意(在子父类覆盖的时候):
(1)、子类抛出的异常必须是父类的异常的子类或者子集!!
(2)、如果“父类“或者”接口“没有异常的抛出,子类覆盖出现异常,只能try不能抛出(原则:子类不能抛比父类多异常)

 

14、创建基本异常类的常用套路:
(1)、如果是自定义的异常类,那么这个类一定要“继承”系统自带的异常类,例如exception!
(2)、自定义的异常类中,自己可以随意定义想要的内容,返回的内容什么的,都是自己定义的。
(3)、如果一个后面自己定义的功能类用到了自己定义的异常类,那么功能类中的“方法”一定要“抛出”前面自定义的异常类创建的“异常对象”!
(4)、并且在定义的“功能类”中加入判断语句,“抛出”前面定义的异常类创建的对象!
(5)、最后一步,主函数调用哪个类中的方法,就是用“该类创建的对象”在try{}...catch(){}语句中进行相应的操作,其中catch语句中一般调用的都是前面自定义的异常类返回的内容!!!

二十六、访问权限

                 public     protected    default    private
同一个类中:     ok         ok            ok          ok

同一个包中:     ok         ok            ok

子类:           ok         ok

不同包中:       ok 

要想使用一个包中的类,就必须要有足够的权限才可以访问,如果一个包中的一个类想要访问另一个包中的类的内容,那么可以使用extends来进行访问,但是正是因为有了extends,别的类也可以通过子类访问“被继承”的类中的内容,这让继承了这个父类的子类相当的受伤,所以,父类中为了只能让子类对其进行访问,可以使用权限protected进行保护,所以在不同包中,类与类之间的访问,如果使用了继承的话,多半要使用protected权限保护!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值