Cet article fait suite à l'article précédent : java - Introduction détaillée à l'orientation objet (1)
11. Accès aux sous-classes à la classe parent et au remplacement de méthode .
Les sous-classes ne peuvent pas accéder directement aux membres privés de la classe parent
Mais les sous-classes peuvent appeler des méthodes non privées dans la classe parent pour accéder indirectement aux membres privés de la classe parent ; classe parente.
Il y a un nom de champ privé dans la classe Person et Student hérite de Person
new Sudent().name
La sous-classe étend le parent ; class (la sous-classe est un cas particulier de la classe parent)
Cause du remplacement de méthode :
La sous-classe doit remplacer la méthode de la classe parent ;
12. super mot-clé et appelant le constructeur de la classe parent
représente la référence par défaut de l'objet de la classe parent
If l'enfant Si une classe souhaite appeler la méthode d'instance substituée de la classe parent, super peut être utilisé comme appelant pour appeler la méthode d'instance substituée de la classe parent.
Utilisez super pour appeler la méthode de la classe parentUtilisez super pour appeler la méthode constructeur de la classe parentAppelez le constructeur
Appelez un autre constructeur surchargé dans cette classe en utilisant ceci (liste de paramètres)
sub Quand une classe Le constructeur appelle le constructeur de la classe parent, utilisez super (liste de paramètres)
Quand une sous-classe appelle le constructeur de la classe parent :
super doit être placé dans la première phrase
Java appellera d'abord le constructeur sans paramètre de la classe parent avant d'exécuter le constructeur de la sous-classe. Le but est d'initialiser les membres hérités de la classe parent.
Lorsqu'une sous-classe crée un objet, elle appelle par défaut le constructeur sans argument de la classe parent. Si le constructeur de la sous-classe spécifie explicitement l'appel d'autres constructeurs de classe parent, il appelle le constructeur de classe parent spécifié, annulez. l'appel au constructeur sans paramètre de la classe parent.
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(); } }
13. Polymorphisme orienté objet
Polymorphisme : fait référence à la même entité ayant diverses formes
Par exemple, si vous allez dans un magasin de nouilles pour manger des nouilles et dites que je veux des nouilles, alors le patron peut me donner des nouilles au bœuf, des nouilles aux œufs, etc.
Cela signifie que "les nouilles " avoir des formes multiples, c'est-à-dire que les entités ont plusieurs formes ;
Le type à la compilation est déterminé par le type utilisé lors de la déclaration de la variable, et le type à l'exécution est déterminé par l'objet réellement attribué à la variable.
Le polymorphisme se produit si le type de compilation et le type d'exécution sont différents.
Exemple :
Prémisse :Student extends Person:
Person p = new Person()
;
Student s = new Student()
;
Person p = new Student()
;/ /Polymorphisme
Relation de référence : les variables de la classe parent pointent vers des objets d'instance de sous-classe
Mécanisme pour implémenter le polymorphisme :
Les variables de référence de la classe parent peuvent pointer vers l'objet d'instance de la sous-classe, et la méthode appelée par le programme est liée dynamiquement pendant l'exécution. Elle fait référence à la méthode de l'objet d'instance réel pointé par la variable, c'est-à-dire à la méthode de l'objet exécuté dans la mémoire. que le type de la méthode de variable de référence définie dans.
Le rôle du polymorphisme :
Traiter différents objets de sous-classe comme classes parents peut masquer les différences entre les différents objets de sous-classe et écrire du code commun et une programmation commune pour s'adapter à l'évolution des besoins .
Modifiez uniquement l'implémentation de la méthode, pas la déclaration de la méthode
L'héritage est une condition préalable au polymorphisme;
Catégorie :
Polymorphisme au moment de la compilation : surcharge de méthode
Polymorphisme au moment de l'exécution : écrasement de méthode
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); } }
Sortie :
Husky mange la nourriture pour chien de Husky !
Les dogue du Tibet mangent de la nourriture pour chiens dogue du Tibet !
14. Conversion de type de variable de référence
Conversion ascendante (sous-classe → classe parent) : (complétion automatique)
Nom de la classe parent Objet de la classe parent = instance de sous-classe ;
Downcast (classe parent → sous-classe) : (achèvement forcé)
Nom de la sous-classe objet de sous-classe = (nom de la sous-classe) instance de classe parent
Nom de l'objet instanceof class ;
Déterminer si le type réel référencé par le nom de variable spécifié à ce moment est la classe ou la sous-classe actuellement donnée
Mon résumé : le type d'objet et les classes doivent avoir des relations d'héritage
Eg: class A extends B{} B b = new A(); If(b instanceof A){ ... }
2、面向对象(2)
1、基本数据类型的包装类
引言:Java提倡的万物皆对象,但是数据类型的划分出现了基本数据类型和引用数据类型,那么我们怎么能把基本数据类型称为对象呢?
除了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
备注:
自动装箱&自动拆箱
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; }
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
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(); } }
静态代码块
使用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("我是普通代码块!"); } }
输出:
我是静态代码块!
我是构造代码块!
我是构造方法!
我是构造代码块!
我是构造方法!
我是普通代码块!
6、构造方法的私有化
有的时候我们为了避免外界创建某类的实例,就将某类的构造方法私有化,即将它的构造方法用private修饰:
外界如何用到?
提供get方法!不提供的话外界就没法创建对象!(对反射无效)
Eg:package reviewDemo; class Stu{ //将构造方法私有化 private Stu(){ } } public class Demo15 { public static void main(String[] args) { Stu s = new Stu(); } }
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) { } }
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) { } }
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();//体现的是多态,父类声明实例化子类对象。而不是抽象类实例化 } }
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();报错!因为抽象类不可以实例化 } }
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(); } }
以上是本次整理的关于java面向对象的详细讲解,后续会为大家继续整理。
文中若有明显错误请指正,谢谢!
Pour plus de questions liées à JAVA, veuillez visiter le site Web PHP chinois : Tutoriel vidéo JAVA
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!