Heim > Java > javaLernprogramm > Java – Detaillierte Einführung in die Objektorientierung (2)

Java – Detaillierte Einführung in die Objektorientierung (2)

王林
Freigeben: 2019-08-23 10:24:55
nach vorne
1964 Leute haben es durchsucht

Dieser Artikel setzt den vorherigen Artikel fort: Java – Detaillierte Einführung in objektorientiertes (1)

11. Unterklassenzugriff auf übergeordnete Klasse und Methodenüberschreibung

Unterklassen können nicht direkt auf die privaten Mitglieder der übergeordneten Klasse zugreifen

Unterklassen können jedoch nicht private Methoden in der übergeordneten Klasse aufrufen, um indirekt auf die privaten Mitglieder der übergeordneten Klasse zuzugreifen Elternklasse.

Es gibt einen privaten Feldnamen in der Person-Klasse und Student erbt Person

new Sudent().name

Unterklasse erweitert das übergeordnete Element Klasse (Unterklasse ist ein Sonderfall der übergeordneten Klasse)

Basiert hauptsächlich auf der übergeordneten Klasse und fügt dann eigene Felder und Methoden hinzu.

Ursache der Methodenüberschreibung:

Wenn eine Methode in der übergeordneten Klasse nicht für die untergeordnete Klasse geeignet ist, verfügt die untergeordnete Klasse über dieselbe Methode wie die übergeordnete Klasse.

Urteilsnirvana: Hinzufügen von @Override, bevor die Unterklassenmethode kompiliert und übergeben werden kann, was darauf hinweist, dass es sich um eine Überschreibung der Methode handelt.

Rufen Sie die überschriebene Methode der übergeordneten Klasse auf: Verwenden Sie den Namen super.method (tatsächlicher Parameter);

Prinzipien, die beim Überschreiben von Methoden (zwei kleine und eine große) befolgt werden sollten:

(Zusammen):

Methodensignaturen müssen gleich sein;

(Zwei kleine):

Der Rückgabewerttyp der Unterklassenmethode ist größer als der Rückgabewerttyp der Methode der übergeordneten Klasse Klein oder gleich  

Die von der Methodendeklaration der Unterklasse ausgelöste Ausnahme sollte kleiner oder gleich der von der Methodendeklaration der übergeordneten Klasse ausgelösten Ausnahme sein;

(Eins): Der Zugriff Die Berechtigung der Unterklassenmethode sollte größer oder gleich der Methode der übergeordneten Klasse sein.

Die Unterklasse muss die Methode der übergeordneten Klasse überschreiben.

Wenn eine Methode der übergeordneten Klasse nicht für das charakteristische Verhalten der Unterklasse selbst geeignet ist, sollte die Methode, die in der übergeordneten Klasse geändert werden soll, überschrieben werden.

12. Super-Schlüsselwort und Aufruf des übergeordneten Klassenkonstruktors

stellt die Standardreferenz des übergeordneten Klassenobjekts dar

If das Kind Wenn eine Klasse die überschriebene Instanzmethode der übergeordneten Klasse aufrufen möchte, kann super als Aufrufer verwendet werden, um die überschriebene Instanzmethode der übergeordneten Klasse aufzurufen.

Verwenden Sie super, um die Methode der übergeordneten Klasse aufzurufen

Verwenden Sie super, um die Konstruktormethode der übergeordneten Klasse aufzurufen


Rufen Sie den Konstruktor auf

Rufen Sie einen anderen überladenen Konstruktor in dieser Klasse mit dieser (Parameterliste) auf

sub Wenn eine Klasse Konstruktor ruft den Konstruktor der übergeordneten Klasse auf, verwenden Sie super (Parameterliste)

Wenn eine Unterklasse den Konstruktor der übergeordneten Klasse aufruft:

super muss im ersten Satz stehen

Java ruft zuerst den parameterlosen Konstruktor der übergeordneten Klasse auf, bevor der Konstruktor der Unterklasse ausgeführt wird. Der Zweck besteht darin, die von der übergeordneten Klasse geerbten Mitglieder zu initialisieren.

Wenn eine Unterklasse ein Objekt erstellt, ruft sie standardmäßig den Konstruktor der übergeordneten Klasse ohne Argumente auf der Aufruf des parameterlosen Konstruktors der übergeordneten Klasse.

Eg:
 
package reviewDemo;
 
 
 
class A{
 
   String name;
 
   A(){
 
      System.out.println("父类默认隐式的构造方法!");
 
   }
 
  
 
   A(String name){
 
      System.out.println("父类显式的构造方法!");
 
   }
 
}
 
 
 
class B extends A{
 
  
 
   B(){
 
      super(null);
 
      System.out.println("子类默认隐式的构造方法!");
 
   }
 
}
 
 
 
public class Demo10 {
 
   public static void main(String[] args) {
 
      new B();
 
   }
 
}
Nach dem Login kopieren

13. Objektorientierter Polymorphismus


Polymorphismus: bezieht sich auf dieselbe Entität mit verschiedenen Formen

Wenn Sie zum Beispiel in einen Nudelladen gehen, um Nudeln zu essen, und sagen, ich möchte Nudeln, dann kann mir der Chef Rindfleischnudeln, Eiernudeln usw. geben.

Das bedeutet „Nudeln“. " haben mehrere Formen, das heißt, Entitäten haben mehrere Formen;

Der Typ zur Kompilierungszeit wird durch den Typ bestimmt, der beim Deklarieren der Variablen verwendet wird, und der Typ zur Laufzeit wird durch das tatsächlich zugewiesene Objekt bestimmt zur Variablen.

Polymorphismus tritt auf, wenn der Typ zur Kompilierungszeit und der Typ zur Laufzeit unterschiedlich sind.

ZB:

Prämisse:Student extends Person:

Person p = new Person();

Student s = new Student();

Person p = new Student();/ /Polymorphismus

Referenzbeziehung: Variablen der übergeordneten Klasse zeigen auf Instanzobjekte der Unterklasse

Mechanismus zur Implementierung von Polymorphismus:

Referenzvariablen der übergeordneten Klasse können auf zeigen Das Instanzobjekt der Unterklasse und die vom Programm aufgerufene Methode werden zur Laufzeit dynamisch gebunden. Es bezieht sich auf die Methode des realen Instanzobjekts, auf das die Variable zeigt, dh auf die Methode des im Speicher ausgeführten Objekts als der Typ der in definierten Referenzvariablen.

Die Rolle des Polymorphismus:

Durch die Behandlung verschiedener Unterklassenobjekte als übergeordnete Klassen können die Unterschiede zwischen verschiedenen Unterklassenobjekten abgeschirmt und gemeinsamer Code und gemeinsame Programmierung geschrieben werden, um sich an sich ändernde Anforderungen anzupassen .

Ändern Sie nur die Implementierung der Methode, nicht die Deklaration der Methode

Vererbung ist eine Voraussetzung für Polymorphismus;

Kategorie:

Polymorphismus zur Kompilierungszeit: Methodenüberladung

Laufzeitpolymorphismus: Methodenüberschreibung

Eg:
 
package test;
 
 
 
class Dog{
 
   void eat(){
 
      System.out.println("一般的狗吃一般的狗粮!");
 
   }
 
}
 
 
 
class HashDog extends Dog{
 
   void eat(){
 
      System.out.println("哈士奇吃哈士奇的狗粮!");
 
   }
 
}
 
 
 
class ZangAoDog extends Dog{
 
   void eat(){
 
      System.out.println("藏獒吃藏獒的狗粮!");
 
   }
 
}
 
 
 
//定义一个动物园喂的方法
 
class Zoo{
 
  
 
   void feed(Dog d){
 
      d.eat();
 
   }
 
  
 
}
 
 
 
public class Demo11 {
 
   public static void main(String[] args) {
 
     
 
      Dog hd = new HashDog();
 
     
 
      Dog zd = new ZangAoDog();
 
     
 
      Zoo z = new Zoo();
 
      z.feed(hd);
 
      z.feed(zd);
 
   }
 
}
Nach dem Login kopieren

Ausgabe:

Husky isst Huskys Hundefutter!

Tibetische Mastiffs fressen Tibetisches Mastiff-Hundefutter!

14. Referenzvariablentypkonvertierung

Aufwärtskonvertierung (Unterklasse → übergeordnete Klasse): (automatische Vervollständigung)

Name der übergeordneten Klasse Objekt der übergeordneten Klasse = Unterklasseninstanz;

Downcast (übergeordnete Klasse → Unterklasse): (erzwungene Vervollständigung)

Unterklassenname Unterklassenobjekt = (Unterklassenname) übergeordnete Klasseninstanz;

Beurteilen Sie, ob der tatsächliche Typ, auf den der angegebene Variablenname zu diesem Zeitpunkt verweist, die aktuell angegebene Klasse oder Unterklasse ist

Meine Zusammenfassung: Der Objekttyp und die Klassen müssen Vererbungsbeziehungen haben

Eg:
class A extends B{}
 
B b = new A();
If(b instanceof A){  ...
}
Nach dem Login kopieren

2、面向对象(2)

1、基本数据类型的包装类

引言:Java提倡的万物皆对象,但是数据类型的划分出现了基本数据类型和引用数据类型,那么我们怎么能把基本数据类型称为对象呢?

Java – Detaillierte Einführung in die Objektorientierung (2)

除了Integer和Character定义的名称和对应的基本类型差异大,其他六种都是将首字母大写就可以了。

Integer,Byte,Float,Double,Short,Long都是Number类的子类。(Number类后面讲);

Character和Boolean都是Object直接子类;

8个类都是final修饰的(不可被继承)。

2、基本数据类型和包装类相互转换

把基本数据类型 → 包装类:

通过对应包装类的构造方法实现

除了Character外,其他包装类都可以传入一个字符串参数构建包装类对象。

包装类 → 基本数据类型

包装类的实例方法xxxValue(); // xxx表示包装类对应的基本数据类型

Eg:
 
boolean bool = false;
 
Boolean b2 = new Boolean(bool);
 
Integer i = new Integer(3);
 
int i2 = i.intValue();
 
Boolean b1 = new Boolean("TRue");//true
 
boolean b2 = b1.booleanValue();
 
Float f = new Float("3.14");//3.14
 
Integer i2 = new Integer("123s");//NumberFormatException
Nach dem Login kopieren

备注:

自动装箱&自动拆箱

jdk1.5开始出现的特性:

自动装箱:可把一个基本类型变量直接赋给对应的包装类对象或则Object对象

自动拆箱:允许把 包装类对象直接赋给对应的基本数据类型

Eg:
 
Integer i = 3;//装箱
 
int i2 = i;//拆箱
 
Object flag = new Boolean(false);
 
if(flag instanceof Boolean){
 
        Boolean b = (Boolean)flag;
 
        boolean b2 = b;
 
}
Nach dem Login kopieren

3、基本类型和String之间的转换

String → 基本类型,除了Character外所有的包装类提供parseXxx(String s)静态方法,用于把一个特定的字符串转换成基本类型变量;

基本类型 → String,String 类有静态方法valueOf(),用于将基本类型的变量转换成String类型。

String str = "17";
int i = Integer.parseInt(str);//String  --> 基本类型
String s1 = String.valueOf(i);//基本类型 --> String
Nach dem Login kopieren

4、Object类

所有类的公共父类,一旦一个类没有显示地继承一个类则其直接父类一定是Object。

一切数据类型都可用Object接收

class OOXX extends Object{}等价于class ooXX {}

常见方法

public boolean equals(Object obj):对象比较

public int hashCode():取得该对象的Hash码

public String toString():对象描述

Object类的 toString()方法:“对象的描述”

建议所有类都覆写此方法

直接打印输出对象时,会调用该对象的toString()方法。//可以不写出来

打印对象的时候,实际调用的对象实际指向的类的自我描述;

全限定类名+@+十六进制的hashCode值,等价于

全限定类名+@+IntegertoHexString(该对象.hashCode)

equals也是判断是否指向同一个对象

没有实际意义,有必要可以重写

public boolean equals(Object obj) {}

String 覆写了 Object的equals方法:只比较字符的序列是否相同

==用于判断两个变量是否相等

基本类型:

引用类型:必须指向同一个对象,才true

只能比较有父子或平级关系的两个对象

new String("1") == new String("1"); ?

5、代码块

代码块指的是使用"{}"括起来的一段代码,根据代码块存在的位置可以分为4种:

普通代码块;

构造代码块;

静态代码块;

同步代码块(线程同步的时候讲解)。

代码块里变量的作用域:

只在自己所在区域(前后的{})内有效;

普通代码块:

普通代码块就是直接定义在方法或语句中定义的代码块:

public void show(){

普通代码块

}

构造代码块:

直接写在类中的代码块:

优先于构造方法执行,每次实例化对象之前都会执行构造代码块。

Eg:
 
public class Demo {
 
    {
 
               System.out.println("我是构造代码块");
 
    }
 
    public Demo(){
 
                System.out.println("我是构造方法");
 
    }
 
    public static void main(String[] args) {
 
               Demo d1  = new Demo();
 
               Demo d2  = new Demo();
 
    }
 
}
Nach dem Login kopieren

静态代码块

使用static 修饰的构造代码块:

优先于主方法执行,优先于构造代码块执行,不管有创建多少对象,静态代码块只执行一次,可用于给静态变量赋值;

Eg:
 
package reviewDemo;
 
/**
 * 测试各代码块的优先级
 * 优先级顺序:静态代码块  > 构造代码块 > 普通代码块
 * 备注:无论创建几个对象,静态代码块只执行一次!
 */
 
 
 
public class Demo13 {
 
   Demo13(){
 
      System.out.println("我是构造方法!");
 
   }
 
   {
 
      System.out.println("我是构造代码块!");//实例化对象的时候才会去调用!
 
   }
 
   static{
 
      System.out.println("我是静态代码块!");
 
   }
 
  
 
   public static void main(String[] args) {
 
      new Demo13();
 
      new Demo13();//再次创建对象,证明无论创建几次对象,静态代码块都只执行一次
 
      System.out.println("我是普通代码块!");
 
   }
 
}
Nach dem Login kopieren

输出:

我是静态代码块!

我是构造代码块!

我是构造方法!

我是构造代码块!

我是构造方法!

我是普通代码块!

6、构造方法的私有化

有的时候我们为了避免外界创建某类的实例,就将某类的构造方法私有化,即将它的构造方法用private修饰:

外界如何用到?

提供get方法!不提供的话外界就没法创建对象!(对反射无效)

Eg:package reviewDemo;
 
 
class Stu{
 
   //将构造方法私有化
 
   private Stu(){
 
     
 
   }
 
}
 
 
 
public class Demo15 {
 
   public static void main(String[] args) {
 
      Stu s = new Stu();
 
   }
 
}
Nach dem Login kopieren

Singleton模式(单例模式) 饿汉式和懒汉式

目的:整个应用中有且只有一个实例,所有指向该类型实例的引用都指向这个实例。

好比一个国家就只有一个皇帝(XXX),此时每个人叫的“皇帝”都是指叫的XXX本人;

常见单例模式类型:

饿汉式单例:直接将对象定义出来

懒汉式单例:只给出变量,并不将其初始化;

我的总结:

饿汉式,static修饰,随着类的加载而加载,会损耗性能,但是方法相对简单

懒汉式 第一次用的时候相对较慢,因为需要加载!线程,不安全!

 
package reviewDemo;
 
//单例模式
 
 
 
//饿汉式,直接把对象构造出来
 
class SingleDemo{
 
   private static SingleDemo s1 = new SingleDemo();
 
   private SingleDemo(){
 
      //提供私有化的构造方法,那么外界就不能构造对象了!
 
   }
 
  
 
   public static SingleDemo getS1() {
 
      return s1;
 
   }
 
}
 
 
 
//懒汉式,先定义,但是不创建对象
 
class SingleDemo2{
 
   private static SingleDemo2 s3 ;
 
  
 
   private SingleDemo2(){
 
      //提供私有化的构造方法,那么外界就不能构造对象了!
 
   }
 
  
 
   public static SingleDemo2 getS3() {//这是一个方法,返回值为创建的对象!
 
      if(s3 == null){
 
         s3 = new SingleDemo2();
 
      }//和饿汉式的区别,此时才来创建对象!
 
      return s3;
 
   }
 
}
 
 
 
public class Demo14 {
 
   public static void main(String[] args) {
 
      SingleDemo s1 = SingleDemo.getS1();
 
      SingleDemo s2 = SingleDemo.getS1();
 
     
 
      SingleDemo2 s3 = SingleDemo2.getS3();
 
      SingleDemo2 s4 = SingleDemo2.getS3();
 
     
 
      System.out.println(s1 == s2);
 
      System.out.println(s3 == s4);
 
     
 
   }
 
}
 
 
 
输出:true true
 
 
 
备注:枚举更加安全些
 
package reviewDemo;
 
 
 
enum Stu{
 
   jake;
 
   //将构造方法私有化起来,反射也不能创建对象,安全
 
   private Stu(){
 
     
 
   }
 
}
 
 
 
public class Demo15 {
 
   public static void main(String[] args) {
 
   }
 
}
Nach dem Login kopieren

8、final 关键字

final可以修饰类,方法,变量。

final修饰类不可以被继承,但是可以继承其他类。

final修饰的方法不可以被覆写,但可以覆写父类方法。

final修饰的变量称为常量,这些变量只能赋值一次。

内部类在局部时,只可以访问被final修饰的局部变量。

final修饰的引用类型变量,表示该变量的引用不能变,而不是该变量的值不能变;

Eg:
 
package reviewDemo;
 
 
 
final class Name{
 
}
 
 
 
class NewName extends Name{//ERROR,报错,因为Name有final修饰
 
}
 
 
 
public class Demo15 {
 
   public static void main(String[] args) {
 
   }
 
}
Nach dem Login kopieren

9、抽象类

当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的行为方式,那么这些方法都有具体的方法体。

但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。

抽象方法的定义:通过abstract关键字来修饰的类称为抽象类;

总结:抽象类用private修饰,里面可以有用private修饰的方法(没有方法体),强制子类进行覆写;

可以理解为:具有某些公共方法的一个总结类。

可以定义被abstract修饰的抽象方法

抽象方法只有返回类型和方法签名,没有方法体。

备注:

抽象类可以含有普通方法

抽象类不能创建实例对象(不能new)

需要子类覆盖掉所有的抽象方法后才可以创建子类对象,否则子类也必须作为抽象类

列举常见的几个抽象类:

流的四个基本父类

InputStream,OutputStream,Reader,Writer

我的总结:

抽象类是类的一种特殊情况:据有类的一切特点,但是不能实例化;一般的都得带有抽象方法。

抽象类不可以实例化,有时看到的近似实例化是多态机制的体现,并不是真正的实例化。

Eg:
 
Socket s = new Socket();
 
OutputStream os = s.getOutputStream();
 
左边是OutputStream类型变量的声明,右边是获取抽象类OutputStream的一个实例对象!
 
 
package testDemo2;
 
 
 
abstract class Person{
 
}
 
 
 
class Student extends Person{
 
}
 
 
public class Demo2 {
 
   public static void main(String[] args) {
 
      Person p = new Student();//体现的是多态,父类声明实例化子类对象。而不是抽象类实例化
 
   }
 
}
Nach dem Login kopieren

abstract方法

分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是功能声明相同,但功能主体不同。

那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。

abstract [非private访问修饰符] 返回值类型 方法名称(参数列表);

抽象方法要存放在抽象类中。

抽象方法也可以存在于接口中

Eg:
 
package reviewDemo;
 
 
 
abstract class Person3{
 
   abstract void show();
 
   abstract void inof();
 
   void turn(){
 
   }
 
}
 
 
 
class NewP extends Person3{
 
   @Override
 
   void show() {
 
   }
 
 
 
   @Override
 
   void inof() {
 
   }
 
   //不覆写的话会报错
 
}
 
 
 
public class Demo15 {
 
   public static void main(String[] args) {
 
      //new Person3();报错!因为抽象类不可以实例化
 
   }
 
}
Nach dem Login kopieren

10、抽象类的体现-模板模式

抽象类是多个具体子类抽象出来的父类,具有高层次的抽象性;以该抽象类作为子类的模板可以避免子类设计的随意性;

抽象类的体现主要就是模板模式设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行拓展,但是子类在总体上大致保留抽象类的行为方式;

编写一个抽象父类,该父类提供了多个子类的通用方法,并把一个或多个抽象方法留给子类去实现,这就是模板设计模式;

模板模式应用的简单规则:

1.抽象父类可以只定义需要使用的某些方法,其余留给子类去实现;

2.父类提供的方法只是定义了一个通用算法,其实现必须依赖子类的辅助;

我的总结:

如果父类的方法不想被子类覆写,那么可以在前面加上final关键字修饰。

Eg:
 
package reviewDemo;
 
//模板模式
 
 
 
//抽象类中包含很多的抽象方法,子类必须去覆写!
 
abstract class Method{
 
   abstract double mul();//返回值类型如果是void的话,下面报错,因为没有返回值,无法引用!
 
   abstract double divid();
 
   void show(){
 
      System.out.println("面积是:"+mul());//周长
 
      System.out.println("面积是:"+divid());//面积
 
   }
 
}
 
 
 
class Square extends Method{
 
   double d;
 
  
 
   public Square(double d) {
 
      super();
 
      this.d = d;
 
   }
 
 
 
   @Override
 
   double mul() {
 
      return d * d;
 
   }
 
 
 
   @Override
 
   double divid() {
 
      return 4 * d;
 
   }
 
}
 
 
 
class Cirle extends Method{
 
   double r;
 
  
 
   public Cirle(double r) {
 
      super();
 
      this.r = r;
 
   }
 
 
 
   @Override
 
   double mul() {
 
      return 2 * 3.14 * r;
 
   }
 
 
 
   @Override
 
   double divid() {
 
      return 3.14 * r * r;
 
   }
 
}
 
 
 
public class Demo16 {
 
   public static void main(String[] args) {
 
      Square s = new Square(5);
 
      s.show();
 
      Cirle c = new Cirle(4);
 
      c.show();
 
   }
 
}
Nach dem Login kopieren

以上是本次整理的关于java面向对象的详细讲解,后续会为大家继续整理。

文中若有明显错误请指正,谢谢!

Weitere Fragen zu JAVA finden Sie auf der chinesischen PHP-Website: JAVA-Video-Tutorial

Das obige ist der detaillierte Inhalt vonJava – Detaillierte Einführung in die Objektorientierung (2). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage