继承的概念和实现 、 super关键字 、 Object常见方法、抽象类、接口、模板方法模式、成员内部类、匿名内部类

这篇博客将会涉及到:

  • 继承的概念和实现
  • super关键字
  • 方法重写—Override
  • Object常见方法

继承的概念:

生活中,继承的概念随处可见,继承需要符合的关系:is-a;父类更通用、子类更特殊更具体。就比如说:动物是一个类,那么它的子类可以是:食草动物、食肉动物。

  • 对于java语言来说,继承背后的思想就是基于已存在的类来构建新类,当从已存在类继承时,就重用了它的方法和属性,还可以添加新的方法和属性来定制新类以应付需求。约定: 从其他类导出的类叫做子类,被导出的类叫做父类。在java中,除了Object类之外,所有类都是子类,都只有唯一父类。就是在创建类的时候,如果不写类继承自哪一个类,系统会默认的认为是Object的子类,通过下图方法可查看,一个类继承的父类:
    在这里插入图片描述
  • 继承在OOP中不可或缺(不写继承自哪一个类会默认继承Object类),创建一个类时总是在继承,继承的意义: 代码重用、体现不同的抽象层次。父子类关系: 父类更抽象,更一般、子类更具体,更特殊。
  • 在java语言中,用extends 关键字来表示一个类继承了另外一个类,如下:
public class Teacher extends Person{
}
  • extends使用示例:
package fhn.demo.java;
class Person{String name;String address;public void eat(){System.out.println("人吃饭");}public void drink(){System.out.println("人喝水");}
}
class Student extends Person{String address;float score;void goToSchool(){System.out.println("去上学");}
}
public class Test {public static void main(String[] args) {Person p=new Person();Student s=new Student();p.name="人";p.eat();p.drink();s.name="学生";s.eat();s.drink();s.goToSchool();}
}

super关键字:

super关键字的特点:

  • super和this关键字的特点类似;super代表的是父类对象的引用
  • 当子父类的成员出现同名时,可以通过super来区分
  • 子类构造方法中,通过super关键字调用父类的构造方法
  • 在子类构造方法中默认都是调用了父类的构造方法super()这个是无参数的,当想调用父类的构造方法是有参数的时候就要自己在子类的第一行输入super(参数)来调用父类的构造方法。
  • 强调: 当构造一个子类对象的时候一定会先调用父类的构造方法来初始化父类的字段。调用父类构造方法的语句必须是子类构造方法中的第一条指令。
  • 注意: 子类只能调用父类的构造方法来初始化参数,当然也可以在自己的构造方法中添加一些父类构造方法没有的语句
  • java继承之私有权限:父类的私有属性和私有方法不会被子类继承,但是可以通过父类的公有方法来间接访问父类的私有属性
class Person{String name;String address;//public Person(){};//无参构造方法,当不写带参数的构造方法,系统会默认的添加无参构造方法public Person(String name,String adress) {//父类的构造方法this.name=name;this.address=adress;System.out.println("父类构造方法被调用");}public void eat(){System.out.println("父类的人吃饭");}public void drink(){System.out.println("父类的人喝水");}
}
class Student extends Person{float score;public Student(String name,String adress) {//子类的构造方法super(name,adress);//在子类的构造方法里面通过super调用父类的构造方法//调用父类构造方法的语句必须是子类构造方法中的第一条指令。/** this.name=name;* this.adress=adress;//这种写法不可以,当父类里面存在无参构造方法时* 					  //子类需要通过super关键字来调用父类的构造方法在自己的构造方法里面进行参数的初始化* */System.out.println("子类构造方法被调用");//当然也可以在自己的构造方法中添加一些父类构造方法没有的语句}void goToSchool(){System.out.println("去上学");}public void eat(){super.eat();//当子父类的成员出现同名时,可以通过super来区分System.out.println("子类的人吃饭");}
}
public class Main {public static void main(String[] args) {Person p=new Person("你们","北京");Student s=new Student("我们","河北");//当构造一个子类对象的时候一定会先调用父类的构造方法来初始化父类的字段p.eat();p.drink();s.eat();s.drink();s.goToSchool();}
}

Object常见方法:

  • java中,所有的类都可以直接或间接继承自java.lang.Object类,可以说Object是java中所有类的祖先即根类。
  • java任何类中都继承了Object类中的方法,主要有:toString()equals()hashcode()clone()getClass()finalize()
  • String toString(): 返回该对象的字符串描述信息。默认输出格式是:类名[字段值,字段值…]。只要对象与一个字符串通过“+”连接,系统就会自动调用toString获得对象的字符串描述符。常被改写:可以根据用户的需求对其进行重写。
  • Boolean equals(): OBject类原始功能是实现判断两个对象是否具有相同的引用,要求判断两个对象状态的相等性。
class Person{String name;String address;//public Person(){};//无参构造方法,当不写带参数的构造方法,系统会默认的添加无参构造方法public Person(String name,String adress) {//父类的构造方法this.name=name;this.address=adress;System.out.println("父类构造方法被调用");}public String toString() {//在子类里面对Object类父类toString方法进行重写//默认返回父亲的toString,return super.toString();return "person message:"+name+address;}public boolean equals(Object arg0) {//对equals进行重写,判断两个类里面的内容知否一致// TODO Auto-generated method stub//return super.equals(arg0);Person p=(Person) arg0;if(this.name==p.name&&this.address==p.address)//java中可用==表示两个字符串是否相等,在C语言中用strcmpreturn true;elsereturn false;}
}
public class Main {public static void main(String[] args) {Person p=new Person("你们","北京");/*不对toString方法进行重写* System.out.println(p.toString());//输出:Person@659e0bfd----Person类名、@659e0bfd是类的内存地址//若果有包名,还会将包名打印出来//默认打印这个对象的地址和相关信息,返回值是字符串类型*///对toSting方法进行重写System.out.println(p.toString());//输出--你们北京Person p2=new Person("你们","北京");/** 不对equals进行重写System.out.println(p2.equals(p));返回的是Boolean类型的值,比较的是两个对象的地址值不是比较两个类的内容是否一致*///方法重写后输出:System.out.println(p2.equals(p));//重写方法后,比较的是两个对象的内容是否一致}
}

继承学习综合练习:

class Wapon
{String name;void WaponAttack(){System.out.println("武器攻击");		}}
class K98 extends Wapon
{void WaponAttack()//重写父类方法{System.out.println("98K攻击");System.out.println("一击毙命");}
}
class Dao extends Wapon
{void WaponAttack()//重写父类方法{System.out.println("砍刀攻击");System.out.println("刀刀见血");}
}
class Play
{String name;String level;Wapon wapon;int id;void attack(){System.out.println("玩家攻击");wapon.WaponAttack();}
}
public class Main {public static void main(String[] args) {Play p1=new Play();p1.name="玩家一";p1.level="青铜";//p1.wapon =new Wapon();p1.wapon =new Dao();//多态p1.attack();//如果直接写这句话,会出现空指针异常,要先给wapon赋值再使用System.out.println();p1.wapon =new K98();//多态p1.attack();//如果直接写这句话,会出现空指针异常,要先给wapon赋值再使用}
}

java继承的简单工厂模式:

  • 工厂模式之前在写智能家居的代码的时候用C语言加链表实现过,在用C语言实现时,就是构建了连个链表分别代表指令工厂和控制工厂,然后将设备通过添加节点的方式插入到对应的链表,在使用的时候,通过设备或者指令名称进行查找然后调用相关的函数,实现起来比较繁琐。
  • 而在java中有了继承的概念,就可以将那些结点看作是继承自一个父类的子类,然后构建一个查找的类对所需要的内容进行查找即可,查找到返回查找的对象的引用,然后就可以调用相关的方法。实现起来比较简单。
class Fruit   //相当于之前用C语言写的链表的头部
{String name;void grow(){System.out.println("野蛮生长的水果");		}public Fruit(String name){this.name=name;		}
}
class Apple extends Fruit
{public Apple(String name){super(name);}void grow()//对父类方法进行重写{System.out.println("野蛮生长的"+name);}
}
class Peach extends Fruit
{public Peach(String name){//构造方法调用父类的构造方法super(name);}void grow()//对父类方法进行重写{System.out.println("野蛮生长的"+name);}
}
class Factory   //在这个类里面进行对水果的查找
{public static Fruit getFruit(String name){if(name=="苹果")return new Apple(name);//这里有用到多态else if(name=="桃")return new Peach(name);else{return null;}}
}
public class Main {public static void main(String[] args) {if(Factory.getFruit("苹果")!=null){System.out.println("找到了苹果");Factory.getFruit("苹果").grow();}if(Factory.getFruit("桃")!=null){System.out.println("找到了桃");Factory.getFruit("桃").grow();}if(Factory.getFruit("葡萄")==null){System.out.println("没有该水果");}}
}

抽象类:

Java中可以定义没有方法体的方法,该方法由子类来具体实现。该没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类。

  • 抽象方法的特点: 只有方法头没有方法体的方法称为抽象方法。 抽象方法用abstract来修饰。 抽象方法代表一种不确定的操作或者行为。 抽象方法不能被调用。 抽象类代表一种抽象的对象类型。 抽象类不能实例化 抽象类中可以有具体方法,可以没有抽象方法。
abstract class Demo1
{abstract public void method();//抽象方法只能放在抽象类里面,在这里声明抽象方法就要将类声明为抽象类
}
class Demo2 extends Demo1 //抽象类使用的时候一般是使用新的类继承抽象类,然后重写里面的抽象方法
{public void method(){System.out.println("Demo2重写的Demo1的方法");}
}
public class Main {public static void main(String[] args) {/** 抽象类在使用的时候不能实例化* 添加函数体则如下所示,对里面的抽象方法进行补充,这种方式算不上实例化,是做的一个匿名的内部类* Demo1 d=new Demo1(){public void method() {}};*/Demo2 d=new Demo2();d.method();}
}

模板方法模式(也是抽象类的一种使用方法):

定义: 一个模板方法用一些抽象的操作定义一个算法,而子类将重定义这些操作以提供具体行为。
意图: 定义了一个操作中的一个算法框架,把一些步骤推迟到子类去实现,模板方法让子类不需要改变算法结构。

具体的代码示例:

abstract class Contrl  //这个控制类只是做一个模板放到这里,因为每一个抽象方法实现不一样
{abstract void initUsart();abstract void getComand();abstract void openCure();abstract void openLight();abstract void OpenTv();public void work()  //这个方法里面是一系列的控制流程里面是抽象方法{initUsart();getComand();openCure();openLight();OpenTv();}
}
class STM32contrl extends Contrl  //继承自contrl这个类然后会让我们实现父类这个抽象类的所有抽象方法
{void OpenTv() {// TODO Auto-generated method stubSystem.out.println("STM32 OpenTv");}void getComand() {// TODO Auto-generated method stubSystem.out.println("STM32 getComand");}void initUsart() {// TODO Auto-generated method stubSystem.out.println("STM32 initUsart");}void openCure() {// TODO Auto-generated method stubSystem.out.println("STM32 openCure");}void openLight() {// TODO Auto-generated method stubSystem.out.println("STM32 openLight");}
}
class C51contrl extends Contrl  //继承自contrl这个类然后会让我们实现父类这个抽象类的所有抽象方法
{void OpenTv() {// TODO Auto-generated method stubSystem.out.println("C51 OpenTv");}void getComand() {// TODO Auto-generated method stubSystem.out.println("C51 getComand");}void initUsart() {// TODO Auto-generated method stubSystem.out.println("C51 initUsart");}void openCure() {// TODO Auto-generated method stubSystem.out.println("C51 openCure");}void openLight() {// TODO Auto-generated method stubSystem.out.println("C51 openLight");}
}
public class Main {public static void main(String[] args) {STM32contrl stm32=new STM32contrl();stm32.work();//STM32contrl这个类也继承了Contrl的work方法,该方法是总的控制流程C51contrl c51=new C51contrl();c51.work();}
}

接口的概念和作用:

接口语法:interface 接口{ //公有静态方法、抽象方法 }

接口的特点: 接口中只能存放静态常量和抽象方法 java接口是对功能的拓展 通过实现接口,java类可以实现多实现 一个类可以同时继承(extends)一个父类并且实现(implement)多个接口 接口与接口之间可以使用extends实现继承。

接口与抽象类的区别:

  • 抽象类和具体实现之间是一个继承关系,也就是如果采用抽象类的方式,则父类和子类在概念上应该是相同的。
  • 接口和实现类在概念上不要求相同,接口只是抽取相互之间没有关系的类的共同特征,而不去关注类之间的关系,它可以使没有层次关系的类具有相同的行为。
  • 抽象类是对一组具有相同属性和行为的逻辑上上有关系的事物的一种抽象,而接口则是对一组具有相同属性和行为的逻辑上不相关的事物的一种抽象。

interface Move
{abstract void eat();abstract void drink();
}
class man implements Move
{public void eat() {System.out.println("人类吃");		}public void drink() {System.out.println("人类喝");		}
}
class animal implements Move 
{public void eat() {System.out.println("动物吃");	}public void drink() {System.out.println("动物喝");		}
}
public class Main {public static void main(String[] args) {new man().drink();new animal().eat();	}
}

内部类:

  • 概念: 所谓的内部类(Inner Class),顾名思义,就是将一个类定义在另一个类的内部,内部的类称之为内部类。
  • 特点: 内部类可以很好的实现隐藏,可以使用protected、private修饰符。 内部类可以直接访问外部类所有成员包括私有成员。 外部类不能直接访问内部类的成员,必须首先建立内部类对象才能访问。
  • 成员内部类及应用: 成员内部类属于外部类的实例成员,成员内部类可以有public、private、default、protected权限修饰符。在成员内部类中访问外部类的成员方法和属性,要使用“外部类名.this.成员方法”和“外部类名.this.成员属性”的形式 。 创建成员内部类的实例使用“外部类名.内部类名 实例=外部类实例名.new 内部类 构造方法(参数)”的形式。
  • 成员内部类有以下限制: 成员内部类不能与外部类重名 不能在成员内部类中定义static属性,方法和类(static、final形式的常量定义除外),因为一个成员内部类实例必然与一个外部类实例关联,static成员完全可以移到其外部类中去。
  • 在一个java文件中只能有一个public类,如果有多个就要放在其他文件中
class Outer
{int data;public Outer(int data) {this.data=data;}void printfData(){System.out.println("外部类打印外部类data:"+data);}class Inner{int data;public Inner(int data) {this.data=data;}void printfData(){System.out.println("内部类打印外部类的data:"+Outer.this.data);System.out.println("内部类打印内部类的data:"+data);}void printouter(){System.out.println("内部类调用外部类方法打印data如下:");Outer.this.printfData();}}
}
public class Main {public static void main(String[] args) {// 创建成员内部类的实例使用 外部类名.内部类名 实例=外部类实例名.new 内部类 构造方法(参数)的形式。Outer Out1=new Outer(10);//创建成员内部类的实例得先创建外部类的实例Outer.Inner In1=Out1.new Inner(20);Out1.printfData();In1.printfData();In1.printouter();}
}

匿名内部类及应用:

  • 内部匿名类: 一个带具体实现的父类或者父接口的匿名的子类对象。
  • 匿名内部类的特点: 匿名内部类是没有名称的内部类,没办法引用他们。必须在创建时,作为new语句的一部分来声明并创建他们的实例。 匿名内部类必须继承一个类(抽象的、非抽象的都可以)或者实现一个接口,所有的父类(或者父接口)是抽象类,则匿名内部类必须实现其所有抽象的方法。
  • 语法: 实例一个匿名内部类----> new interface/superclass(){类体}这形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口,并同时创建该匿名类的一个新实例。
abstract class Demo
{abstract void printfInfo();abstract void interPrintf();//在接口中默认是抽象方法
}
interface Demo2
{void interPrintf();//在接口中默认是抽象方法
}
public class Main {public static void main(String[] args) {new Demo(){void printfInfo() {System.out.println("这不是demo类的实例化,而是匿名内部类的方法");}void interPrintf() {System.out.println("所有的父类(或者父接口)是抽象类,则匿名内部类必须实现其所有抽象的方法");}}.printfInfo();//		Demo d=new Demo(){这种形式是以多态的形式创建匿名内部类,new Demo()是Demo 的子类的对象,在这里用父类引用来接收的
//			void printfInfo() {
//				System.out.println("这不是demo类的实例化,而是匿名内部类的方法");
//			}
//			void interPrintf() {
//				System.out.println("所有的父类(或者父接口)是抽象类,则匿名内部类必须实现其所有抽象的方法");
//			}
//		};
//		d.interPrintf();
//		d.printfInfo();new Demo2(){public void interPrintf() {System.out.println("这不是接口的实例,而是匿名内部类的方法");				}}.interPrintf();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

盘点关于程序员的10个有趣的段子

(1)程序员的读书历程:x 语言入门 —> x 语言应用实践 —> x 语言高阶编程 —> x 语言的科学与艺术 —> 编程之美 —> 编程之道 —> 编程之禅—> 颈椎病康复指南。(2)程序员最讨厌的四件事&#x…

Linux 用户管理命令笔记

目录 1、新增用户 2、删除用户 3、修改用户 4、修改用户密码 1、新增用户 useradd user1 用户创建流程 1、系统先将用户信息记录在/etc/passwd中,一般会在/etc/passwd和/etc/shadow末尾,同时分配该用户UID。 2、创建用户目录,一般创建路径/home目录中。…

tomcat依赖导入步骤_Tomcat长生不老之术——嵌入式

前言Tomcat是一个非常流行的Web服务器,用于部署和运行Java Web应用程序。一般情况下,我们都是在单独的Tomcat实例上运行自己的Web应用,其实与这种经典方案相比,我们可以将服务器运行时直接集成到应用程序中,从而更加的…

Linux用户组笔记整理

目录 一、Linux用户组概念 二、常用命令 三、用户组信息存储位置 一、Linux用户组概念 Linux用户组(group)就是具有相同操作权限范围的Linux用户管理起来; 比如有时我们要让同一类用户具有相同的权限,比如查看、修改某一文件或执…

Linux文件操作实用笔记

Linux系统遵循一切皆是操作文件的规则。所以想用好Linux系统,就必须要掌握文件相关的操作。 1、创建文件命令:touch 语法格式: touch filename #filename 文件名称。 比如 touch hello.txt就会在当前木创建一个hello.txt的文件。 说明&#x…

安装完CentOS 7 后必做的七件事

CentOS是最多人用来运行服务器的 Linux 版本,最新版本是 CentOS 7。当你兴趣勃勃地在一台主机或 VPS 上安装 CentOS 7 后,首要的工作肯定是加强它的安全性,以下列出的七件事,是你进一步配置系统和安装其他软件前必须做的。 1. 更改…

python显示小数点后几位数_python窗口编程-3:数位处理(整数)

我们在上一次课程中(python窗口编程-2:风格与布局 ),制作了完整的计算器窗口界面,只是那个窗口没有真正的功能,是点击任何按钮都会关闭。这一次,我们加入一些事件处理的功能,让它成为一个正常工作的窗口程序…

Linux文件目录基础笔记

1、进入目录名称:cdcd命令主要是方便用户切换到不同目录的指令。比如:cd #只执行cd命令默认进入root的根目录cd /home #进入home目录,如果home目录有testdir目录的话,可以执行 cd testdir 进入testdir目录。2、创建目录命令&#…

eclipse安卓工程的构建、配置连接模拟器、安卓工程结构介绍

安卓工程构建及第一个安卓程序运行: 首先新建安卓工程: 然后填写APP信息,下面的包名一般都是公司域名的倒写,包名中不能有中文,否则会报错。 然后配置一些安卓app的选项 有关app启动的图标(就像QQ的企鹅一…

Linux中su和sudo的用法整理

一、为什么会有su和sudo命令?主要是因为在实际工作当中需要在Linux不同用户之间进行切换。root用户权限最高很多时候需要root用户才能执行一些关键命令。所以需要临时切换为root用户。工作完成后,考虑到系统的安全性避免误操作需要切换为普通用户。su和s…

codeforces 650B - Image Preview

题意:给你n个照片,从第一个照片开始看,如果一张照片是w,那么要花费b时间去反转他,否则不用反转,看一张从来没看过的照片要1时间, 从一张滑动到另一张要a时间。如果一张照片看过,则不…

asp js单步调试_如何使用Chrome的控制台高效的调试Javascript代码?

引言在我们的日常开发中我们常常会遇到JavaScript的调试问题,而我们解决问题的传统解决方案就是使用大量的console.log或者console对象的其他方法,这会给我们带来很多不便,特别是遇到复杂问题的时候,可能会出现大量的console.log&…

安卓App的启动过程、安卓布局分类及布局和页面的关系

Android App 启动流程: 当你想要启动一个app时,首先得点击该app桌面图标。那点击图标时到底发生了什么呢?先看个理论知识 .Launcher: launcher其实就是一个app,从功能上说,是对手机上其他app的一个管理和启动,从代码…

Linux文件默认权限和umask笔记

关于Linux文件默认权限的问题,可以实际先尝试一下如下命令:root用户登录[rootlocalhost test]# touch file1[rootlocalhost test]# ls-l file1-rw-r--r-- 1 root root 0 May 5 08:28 file1 #输出结果 对应的数字权限 644[rootlocalhost test]# touch fi…

Android相对布局(RelativeLayout)常用属性、练习使用按键、文本框等控件、线性布局(LinearLayout)属性

RelativeLayout中子控件常用属性: 子控件默认是从父控件的左上角开始排列的 相对于父控件 android:layout_alignParentTop"true" 和父控件的顶部对齐android:layout_alignParentBottom"true" 和父控件的底部对齐android:layout_alignPar…