4:面向对象高级

继承弊端:打破了封装性。

final关键字:

1,final是一个修饰符,可以修饰类,方法,变量。

2,final修饰的类不可以被继承。

3,final修饰的方法不可以被覆盖。

4,final修饰的变量是一个常量,只能赋值一次。

 为什么要用final修饰变量。其实在程序如果一个数据是固定的,

 那么直接使用这个数据就可以了,但是这样阅读性差,所以它该数据起个名称。

 而且这个变量名称的值不能变化,所以加上final固定。

写法规范:常量所有字母都大写,多个单词,中间用_连接。

抽象类:

抽象:笼统,模糊,看不懂!不具体。

特点: 

1,方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰。

 抽象方法必须定义在抽象类中。该类必须也被abstract修饰。

2,抽象类不可以被实例化。为什么?因为调用抽象方法没意义。

3,抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化。

 否则,这个子类还是抽象类。

1,抽象类中有构造函数吗?

 有,用于给子类对象进行初始化。

2,抽象类可以不定义抽象方法吗? 

 可以的。 但是很少见,目的就是不让该类创建对象。AWT的适配器对象就是这种类。

 通常这个类中的方法有方法体,但是却没有内容。

abstract class Demo {  void show1()  {}  void show2()   {} }

3,抽象关键字不可以和那些关键字共存? 

 private 不行 ,private进行了封装

 static 不行 ,通过类名.方法调用没有意义

 final 不行,final代表最终的,不能被重写

4,抽象类和一般类的异同点。 

 相同点:

  抽象类和一般类都是用来描述事物的,都在内部定了成员。

 不同:

  1,一般类有足够的信息描述事物。

     抽象类描述事物的信息有可能不足。

  2,一般类中不能定义抽象方法,只能定非抽象方法。

     抽象类中可定义抽象方法,同时也可以定义非抽象方法。

  3,一般类可以被实例化。

     抽象类不可以被实例化。

5,抽象类一定是个父类吗? 

 是的。因为需要子类覆盖其方法后才可以对子类实例化。 

接口

定义接口使用的关键字不是class,是interface.

/*

对于接口当中常见的成员:而且这些成员都有固定的修饰符。

1,全局常量: public  static final

2,抽象方法。public abstract  

由此得出结论,接口中的成员都是公共的权限.

interface Demo{ public static final int NUM = 4; public abstract void show1(); public abstract void show2();}

类与类之间是继承关系,类与接口直接是实现关系。

接口不可以实例化。 

只能由实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实例化。 

否则,这个子类就是一个抽象类。

修饰符 class 类名 extends 父类implements 接口1,接口2。。。

{类体部分 ,如果继承了抽象类,需要实现继承的抽象方法;要实现接口中的抽象方法}

interface QQ extends  CC,MM//接口与接口之间是继承关系,而且接口可以多继承。{ void function();}class WW implements QQ{//覆盖3个方法。 public void show(){} public void method(){} public void function(){}}

抽象类和接口的异同点:

相同点: 

 都是不断向上抽取而来的。

不同点: 

 1,抽象类需要被继承,而且只能单继承。

    接口需要被实现,而且可以多实现。

 2,抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。

    接口中只能定义抽象方法,必须由子类去实现。

 3,抽象类的继承,是is a关系,在定义该体系的基本共性内容。

    接口的实现是 like a 关系,在定义体系额外功能。


多态

对象的多态性。

class 动物 

{}

class 猫 extends 动物 

{}

class 狗 extends 动物 

{}

猫 x = new 猫(); 

动物 x = new 猫();//一个对象,两种形态。 

猫这类事物即具备者猫的形态,又具备着动物的形态。 

这就是对象的多态性。

简单说:就是一个对象对应着不同类型.

多态在代码中的体现: 

 父类或者接口的引用指向其子类的对象。

多态的好处:

 提高了代码的扩展性,前期定义的代码可以使用后期的内容。

多态的弊端: 

 前期定义的内容不能使用(调用)后期子类的特有内容。

多态的前提:

 1,必须有关系,继承,实现。

 2,要有覆盖。 

Animal a = new Cat(); //自动类型提升,猫对象提升了动物类型。但是特有功能无法访问。

作用就是限制对特有功能的访问。

专业讲:向上转型。将子类型隐藏。就不用使用子类的特有方法。

如果还想用具体动物猫的特有功能。

你可以将该对象进行向下转型。

 Cat c = (Cat)a;//向下转型的目的是为了使用子类中的特有方法。

c.eat();

c.catchMouse();

注意:对于转型,自始自终都是子类对象在做着类型的变化。 

public static void method(Animal a) {  a.eat();  if(a instanceof Cat)//instanceof:用于判断对象的具体类型,只能用于引用数据类型判断 //通常在向下转型前用于健壮性的判断, 如果传入了其他的东西就不能调用  {    Cat c = (Cat)a;   c.catchMouse();  }  else if(a instanceof Dog)  {   Dog d = (Dog)a;   d.lookHome();  }

多态时, 成员的特点: 

1,成员变量。

 编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。

 运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。

 简单说:编译和运行都参考等号的左边。哦了。

 作为了解。

2,成员函数(非静态)。 

 编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。

 运行时:参考的是对象所属的类中是否有调用的函数。

 简单说:编译看左边,运行看右边。

因为成员函数存在覆盖特性。 

3,静态函数。 

  编译时:参考引用型变量所属的类中的是否有调用的静态方法。

  运行时:参考引用型变量所属的类中的是否有调用的静态方法。

  简单说,编译和运行都看左边。

  其实对于静态方法,是不需要对象的。直接用类名调用即可。


内部类

内部类访问特点:

1,内部类可以直接访问外部类中的成员。

2,外部类要访问内部类,必须建立内部类的对象。

一把用于类的设计。

分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容。 

这时就是还有的事物定义成内部类来描述。

class Outer{ private static int num = 31; class Inner// 内部类 {  void show()  {   System.out.println("show run..."+num);  }  /*static void function()//如果内部类中定义了静态成员,该内部类也必须是静态的  {   System.out.println("function run ...."+num);  }  */ } public void method() {  Inner in = new Inner();  in.show(); }}

在类的外部如何访问内部类对象?

对于非静态内部类

①先创建外部类对象,然后再创建内部类对象

OuterClass oc=new OutClass();

InnerClass ic=oc.new InnerClss();

ic.test();

class InnerClassDemo

{

 public static void main(String[] args)

 {

②Outer out = new Outer();

out.method(); 这是创建一个方法访问

③直接访问外部类中的内部类中的成员。

Outer.Inner in = new Outer().new Inner();

in.show();

静态内部类:内部使用static来修饰,所以创建该类的对象可以没有外部类对象

 如果内部类是静态的。 相当于一个外部类

Outer.Inner in = new Outer.Inner();

 in.show();

如果内部类是静态的,成员是静态的。

Outer.Inner.function();

 } 

}

为什么内部类能直接访问外部类中成员呢?

那是因为内部类持有了外部类的引用。  外部类名.this

class Outer

{

 int num = 1;

 class Inner

 {

  int num = 2;

  void show()

  {

   int num = 3;

System.out.println(num);//3

 System.out.println(this.num);//2

 System.out.println(Outer.this.num);//1

如果外部成员变量是int a=1,这里直接写就行,即名称不一样的时候上面这样写

 }

 }

 void method()

 {

  new Inner().show();//匿名对象

 }

}

class InnerClassDemo2

{

 public static void main(String[] args)

 {

  new Outer().method();

 }

}

注意:静态内部类中的方法不能访问外部内的非静态成员

内部类可以存放在局部位置上。

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

class Outer { int num = 3; Object method() {final int x = 9;   class Inner   {   public String toString()    {    return "show ..."+x;   }  }

匿名内部类。就是内部类的简写格式。

在类的内部直接创建一个接口的实现类对象  

必须有前提: 

 内部类必须继承或者实现一个外部类或者接口。

匿名内部类:其实就是一个匿名子类对象。  

格式:new 父类or接口(){子类内容}

abstract class Demo{ abstract void show();}class Outer{ int num = 4; /* 正常情况 class Inner extends Demo {  void show()  {   System.out.println("show ..."+num);  } } */ public void method() {  //new Inner().show();  new Demo()//匿名内部类。 直接内容写进去  {   void show()   {    System.out.println("show ........"+num);   }  }.show(); //可以调用,也可以不调用 }}class InnerClassDemo4{ public static void main(String[] args) {  new Outer().method(); }}

通常的使用场景之一:

当函数参数是接口类型时,而且接口中的方法不超过三个。

可以用匿名内部类作为实际参数进行传递?

不是太懂,参见day10 InnerClassDemo5.java

class Outer{ void method() {  Object obj = new Object() //匿名内部的特征就是直接在()后写内部内容  {   public void show()   {    System.out.println("show run");   }  };  obj.show();//因为匿名内部类这个子类对象被向上转型为了Object类型。     //这样就不能在使用子类特有的方法了。 } }class InnerClassDemo6{ public static void main(String[] args) {  new Outer().method(); }}

Eg:

New IplayGame(){

Public void playGame(){

Sysout(用匿名内部类实现接口)}

}.playGame();

也可以在类的内部这样写:

IplayGame ip= new iplayGame(){

   Public void playGame(){

   Sysout(“使用匿名内部类实现接口”)}};

   Ip.playGame();//通过这样访问这个方法


Object类:

它是所有类的根父类

  1. Object类的变量可以指向任何类型的对象
  2. Object是不断抽取而来,具备着所有对象都具备的共性内容。
  3. Objict的方法,参数类型是Object类型,所以可以传入任何参数

默认为:Object obj=new person()

==和equals:

1.==:对于引用类型,表叫俩个对象的内存地址是否相同,要求俩边对象是类型兼容的,若不兼容,则编译出错

2.Object类的equals方法:原义是比较俩个对象的内存地址是否相同,可以传入任何对象,通常情况我们

是比较俩个参数的值是否相同,所以可以根据业务的需要重写该方法,步骤:

Public boolean equals(object obj)

①检验传入的为person类型,若不是,直接返回false

If(!(Obj instanceof person))

Return false;

②若是person类型,则先进行强制转换

Person person=(person)obj

③比较name和age

If(name.equals(person.name)&&age==person.age)

Return ture;

Return false;

Tostring()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址(哈西码)

在进行String与其他类型数据连接操作时,自动调用tostring()方法

Date now=new date();

Sysout(now)相当于sysout(now.tostring())

输出的是date@12332

一般开发时重写该方法

S1=”hello”;

Sysout(s1)

System.out.println(p1.toString());//Person@61de33

hashCode方法

当equals方法重写时,通常有必要重写hashcode方法 ,因为内容相同,地址也得相同,才能叫一样

getClass方法

获取当前对象所属的字节码文件对象

Class clazz1 = p1.getClass();

Class clazz2 = p2.getClass();

System.out.println(clazz1==clazz2);

System.out.println(clazz1.getName());

getClass().getName()获取字节码文件对象的名称:person

getClass().method()获取字节码文件对象的方

System.out.println(p1.getClass().getName()+"$"+Integer.toHexString(p1.hashCode()));//Person@61de33

Integer.toHexString:10进制转换16进制,工作时经常用,因为能短点

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏顶级程序员

Java中的反射总结

刚开始学习Java的时候真的很难理解反射到底是个什么东西 一些书籍,哪怕是很经典的书籍都解释的让人感觉懵懵的,或许的确是我太笨 况且,网上说在将来学习框架的时...

35850
来自专栏小詹同学

程序员面试必备之排序算法汇总(下)

希望小小詹同学学习同时能便于他人~ ---- 本文用Python实现了快速排序、插入排序、希尔排序、归并排序、堆排序、选择排序、冒泡排序共7种排序算法。上篇已...

357100
来自专栏小樱的经验随笔

【Java学习笔记之二十六】深入理解Java匿名内部类

     在【Java学习笔记之二十五】初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客。在这篇博...

34960
来自专栏LanceToBigData

面试题(一)关于内部类的面试题

一、看下面代码求值 1 /要求:使用已知的变量,在控制台输出30,20,10。 2  class Outer { 3 p...

22060
来自专栏WindCoder

Java漫谈-数组

在Java语言中,数组是对象(An object is a class instance or an array.),而且是动态创建的。

19810
来自专栏C语言及其他语言

【编程经验】关于数组指针与指针数组的解释

啦啦啦啦,小编又来了呢,今天给大家讲讲数组指针与指针数组,依旧废话不多说,直接步入正题。 关于数组指针和 指针数组,相信狠很多同学对此疑惑过,今...

28850
来自专栏企鹅号快讯

Python网络爬虫之正则表达式

正则表达式非Python独有,在Python中通过re库模块实现。 ? 下面是一些常见的匹配模式 ? re.match re.match尝试从字符串的起始位置匹...

193100
来自专栏ml

关于如何来构造一个String类

  今天帮着一位大二的学弟写了一个String的类,后来一想这个技术点,也许不是什么难点,但是还是简单的记录一些吧! 为那些还在路上爬行的行者,剖析一些基本的实...

37750
来自专栏拭心的安卓进阶之路

深入理解 Java 反射:Class (反射的入口)

深入理解 Java 反射系列: 深入理解 Java 反射:Class (反射的入口) 深入理解 Java 反射:Field (成员变量) 深入理解 Java ...

285100
来自专栏流媒体

C++多态

当类存在虚函数时,编译器会为该类维护一个表,这个表就是虚函数表(vtbl),里面存放了该类虚函数的函数指针。在构造类的时候增加一个虚表指针(vptr)指向对应的...

12030

扫码关注云+社区

领取腾讯云代金券