java的类和继承构造

 一些小技巧

类和对象

什么是类,对象,方法?

在下面的 Java 代码中,定义了一个名为 Person 的类,并提供了构造方法来初始化对象的属性。类中定义了 eatsleepwork 三个方法,用于表示人的行为。在 main 方法中,创建了一个名为 p1Person 对象,并调用了其方法来展示人的行为。

通过这样的代码组织,我们可以创建多个不同的 Person 对象,每个对象都有自己独立的属性和行为。

public class Person {//属性private String name;private int age;private String gender;public Person(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}//方法,也就是行为public void eat() {System.out.println(name + " is eating.");}public void sleep() {System.out.println(name + " is sleeping.");}public void work() {System.out.println(name + " is working.");}public static void main(String[] args) {//实例化了一个p1的对象Person p1 = new Person("Tom", 25, "male");p1.eat();p1.sleep();p1.work();}
}

1)在java中,类只支持单继承,不允许多重继承,也就是说,一个类只能有一个直接的父亲,例如下面这种情况是不合法的

class A{}
class B{}class C extends A,B
//这种写法是错误的

2)但是多个类可以同时继承一个父亲

class A{}class B extends A{}
class C extends A{}

3)多层继承也是可以的

这时候C也可以被称作A的子类

class A{}class B extends A{}
class C extends B{}

封装

class Animal{private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

就近原则

this指针的作用

总结

static修饰符

1.静态变量

特点:

1.可以通过类名直接访问

2.静态变量是随着类的加载而加载,是优先于对象出现的

静态变量被所有对象共享,什么意思?

下面是例子,

展示了静态变量可以通过类名访问,且被所有对象共享

调用静态变量的方法

2.静态方法

这里引入了一个新的概念——工具类,借此来整合一下目前遇到的所有类

工具类:帮助我们做一些事情,但是不描述任何事物的类。

特点:

1.见类名知其作用

2.私有化构造方法(使该类无法被示例化)

3.方法定义为静态的(不用实例化对象,也可以调用方法)

举例,计算器的类就可以被看作是工具类,因为不需要实例化对象,只需要调用方法就够了

public class ArrayUtil {//私有化构造方法,为了不让外界实例化对象private ArrayUtil() {};//定义为静态方法,方便调用public static void printArr(int[] arr) {StringBuilder sb = new StringBuilder();sb.append("[");for (int i = 0; i < arr.length; i++) {if(i==arr.length-1) {sb.append(arr[i]);}else {sb.append(arr[i]);sb.append(",");}}sb.append("]");System.out.println(sb.toString());}public static double getAverge(int[] arr) {double sum =0;for (int i = 0; i < arr.length; i++) {sum+=arr[i];}return sum/arr.length;}}
public class testCalc {public static void main(String[] args) {int[] arr = {1,2,3,4,5};ArrayUtil.printArr(arr);double ret = ArrayUtil.getAverge(arr);System.out.println(ret);}}

继承

继承的使用方法和好处

继承的特点

如果一个类没有父类,则默认继承于object 

可以看到,下层子类拥有上层父类的特点

继承的权限

1.子类继承了父类中的哪些内容?

总结:

1.构造方法一律不可以被继承的

2.成员变量一律可以被继承。(但是子类虽然能继承父类的private,却不能访问)

3.成员方法非私有可以被继承,私有不能被继承

2.子类能访问父类中哪些属性?

在子类中,只允许直接访问父类中非private的属性和方法,换句话说,父类中private修饰的属性和方法在子类中无法直接访问,但是可以用gettersetter方法间接访问

class Animal{//父类private int age;public int getAge(){return age;}String name;
}
class Dog extends Animal{//子类extends(继承)父类String color;void print(){System.out.println(age);//直接访问父类中的private属性,错误!System.out.println(name);//父类中的name为default权限,可以访问}
}

子类在父类基础上的操作

1.子类在父类基础上扩充属性和方法

子类已经拥有父类的所有属性和方法,扩充子类的属性和方法,让子类描述的对象更加具体

如下。Dog类示例化的对象首先会拥有Animal类的两个属性,并在此基础上扩充了一个颜色属性

class Animal{//这是父类int age;String name;
}
class Dog extends Animal{//子类extends(继承)父类String color;
}

2.对子类继承自父类的方法进行重写(override)

为了满足不同需求,子类可以对父类的方法重写。

public class Main {public static void main(String[] args) {Dog d = new Dog();d.shout();}
}
class Animal{//这是父类int age;String name;void shout(){System.out.println("发出了奇怪的叫声");}
}
class Dog extends Animal{//子类extends(继承)父类String color;void shout(){//重写System.out.println("发出了汪汪汪的叫声");}
}

注意,子类中重写方法的权限不得低于父类中原方法的权限

class Animal{//这是父类int age;String name;void shout(){System.out.println("发出了奇怪的叫声");}
}
class Dog extends Animal{//子类extends(继承)父类String color;private void shout(){//这样重写就错了System.out.println("发出了汪汪汪的叫声");}
}

3.虚方法表

如果A类想调用方法C,是在A类找方法C,找不到去B类找,然后再去C类找,是这样吗?

不是的,因为效率太低了,于是有了虚方法表。

对象类型转化

1.只有当两种类型有继承关系时,才能对象类型转换

2.向上类型转换。即子类转换成父类,这说无需强制类型转换的,因为父类有的东西子类肯定也有。转换完后,只能使用父类中的方法。因为已经变成父类的类型了,自然不能调用子类的方法。语法格式如下

fatherClass obj = new sonClass();

3.向下类型转换(强制类型转换)。这个操作有约束条件的。向下转型通常发生在父类类型的引用指向子类对象的情况下。确保在进行向下转型之前,引用确实指向了正确的子类对象,否则可能会出现运行时异常。

sonClass obj = (sonClass) fatherClass;

interface Animal{void eat();void sleep();
}interface Pet extends Animal{void play();void bark();
}class Teddy implements Pet{public void bark() {System.out.println("汪汪汪");}@Overridepublic void eat() {// TODO Auto-generated method stubSystem.out.println("吃骨头");}@Overridepublic void sleep() {// TODO Auto-generated method stubSystem.out.println("睡懒觉");}@Overridepublic void play() {// TODO Auto-generated method stubSystem.out.println("和主人玩");}}public class testCalc {public static void main(String[] args) {//创造Teddy对象并向上转型(无需强制类型转换)Pet teddy = new Teddy();teddy.eat();teddy.sleep();teddy.play();//teddy.bark(); //这样就不行了,因为teddy现在是Pet类型,而bark方法是Teddy类里的//向下转型(强制类型转换)if(teddy instanceof Teddy) {//如果teddy此时的类型确实是Teddy类的父类//那么可以进行向下转型teddy = (Teddy)teddy;teddy.bark();}}}

抽象类

1.为什么要有抽象类?

例如我们定义了一个Person类,里面的work方法是空着的(或者随便写一个,就像图中一样),这是因为,不同的人的工作是不同的,无法统一,因此无法在Person类里把work方法写好,换言之,有不确定的方法体。

需要依靠对象进行重写。

当我们去实例化老师和学生这两个对象的时候,student和teacher两个对象需要对work方法进行重写。但倘若忘记重写或没有重写,就不合适了。为了防止忘记重写的情况发生,我们要用上抽象类来“逼”对象进行重写,怎么个“逼”法?往下看。

像这样定义了一个抽象类,类中的抽象方法,子类必须强制进行重写,否则会报错。

抽象类和抽象方法的定义格式

注意!有抽象方法所在的类必须定义成抽象类!

public abstract class AbstractClass {//抽象类// 抽象方法//需要注意的是,抽象方法括号()完直接加封号;public abstract void abstractMethod();// 普通方法public void concreteMethod() {// 方法体}
}

当子类继承了抽象类之后,需要重写抽象方法。重写抽象方法的格式如下:

public class ConcreteClass extends AbstractClass {@Overridepublic void abstractMethod() {// 实现抽象方法的具体逻辑}
}

抽象类和抽象方法的注意事项

1.抽象类不能实例化

2.抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

3.抽象类可以有构造方法(可以有疑惑,既然不能实例化为什么还要有构造方法呢?因为构造方法可以用于初始化成员变量)

4.抽象类的子类,要么重写抽象类中所有的抽象方法,要么这个子类也是个抽象类

接口

为什么要有接口?

  1. 多继承:Java中的类只支持单一继承,但是通过接口,一个类可以实现多个接口,从而获得了类似于多继承的特性。这使得Java中的类能够更加灵活地组合和复用代码。同时,避免了多继承所带来的复杂性和歧义性。

  2. 解耦:接口可以将抽象和实现分离,从而降低了代码之间的耦合度。使用接口能够让程序更容易扩展和维护,因为实现类只需关注接口定义的方法即可,而不需要关心具体的实现细节。

  3. 规范约束:接口定义了一组行为规范,使得类能够按照这些规范进行设计和实现。这有助于提高代码的可读性、可维护性和可扩展性。

  4. 多态性:接口与多态性密切相关,接口的引用变量可以指向实现了该接口的任何类的对象,从而实现了对不同类的统一处理。

举个例子,现在有个游泳的功能,写到动物类里是不合适的。因为不是所有动物都会游泳,所以可以把游泳功能写成一个接口,单独提供给能游泳的动物。

abstract class Animal{//方法有抽象类,那么整个类也要变成抽象类private String name;private int age;public Animal() {super();// TODO Auto-generated constructor stub}public Animal(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public abstract void eat();//因为每个动物都有自己吃的东西,无法统一行为//干脆不写,直接把eat方法修饰为抽象类}//因为总共有兔子,青蛙,狗三种动物
//兔子不会游泳,所以不能把swim行为加在Animal类里
//但是如果在青蛙和狗的类里单独加Swim,可能会导致不统一
//因为青蛙里的可能叫swim,狗里的叫swimming,这就不统一了
//所以要定义一个swim接口,谁会游泳谁就继承,然后在自己的类里重写即可
interface Swim{public void Swim();
}class Frog extends Animal implements Swim{@Overridepublic void Swim() {System.out.println("蛙泳");}@Overridepublic void eat() {// TODO Auto-generated method stubSystem.out.println("吃蚊子");}}class Dog extends Animal implements Swim{@Overridepublic void Swim() {System.out.println("狗刨式");}@Overridepublic void eat() {// TODO Auto-generated method stubSystem.out.println("吃骨头");}}class Rabbit extends Animal{@Overridepublic void eat() {System.out.println("吃胡萝卜");}public Rabbit() {super();// TODO Auto-generated constructor stub}public Rabbit(String name, int age) {super(name, age);// TODO Auto-generated constructor stub}}

接口的注意事项

  1. 抽象方法接口中的方法都是抽象方法,不包含具体的实现代码;

  2. 多继承:Java中的类可以实现多个接口,这使得Java支持了接口的多继承性质;

  3. 关键字:在Java中,使用interface关键字来声明一个接口;

  4. 实现:类通过使用implements关键字来实现一个或多个接口,实现接口的类必须提供接口中定义的所有方法的具体实现;(有点像继承抽象类)

  5. 接口之间的继承接口可以继承其他接口(但并不实现,因为接口是不包含具体的实现代码),使用extends关键字;

  6. 常量:接口中可以包含常量,这些常量默认为public static final类型;

接口和抽象类的异同

相似之处:

  1. 抽象性:接口和抽象类都是抽象的,它们不能被实例化,只能被子类实现或继承。
  2. 约束子类:它们都可以用于约束子类,使得子类必须实现或重写其中定义的方法。
  3. 实现方法:在接口和抽象类中都可以定义方法的签名而不提供具体实现

区别:

  1. 方法实现:接口中的方法都是抽象的,没有方法体;而抽象类中可以包含抽象方法,也可以包含具体的方法实现。

  2. 多继承:在Java中,一个类只能继承一个抽象类,但可以实现多个接口。这意味着接口支持多继承,而抽象类不支持。

  3. 构造方法:抽象类可以有构造方法,而接口不能有构造方法。

  4. 成员变量:抽象类中可以包含成员变量,而接口中的变量默认为public static final类型的常量。

  5. 设计目的:抽象类用于表示一种“is-a”关系,即子类是父类的一种特殊类型;而接口更多地用于表示一种“has-a”关系,即类具有某种特定的行为能力

综上所述,抽象类和接口在某些方面确实有相似之处,但它们的设计目的和使用场景有所不同。一般来说,如果需要表示一种层次结构,并且希望共享代码或者包含成员变量,可以使用抽象类;而如果需要表示一种行为规范,并且希望实现多重继承,可以使用接口。

该怎么规范简洁地写接口?

例题

写之前要先画图,提取共同特征到父类,特殊行为用接口实现

以下的思路对吗?是对的,但不够简洁规范。

因为父类的所有子类都应该是同一种事物,但教练和运动员不是同一种事物,因此可以再分类

修改过后,简洁很多

//因为创建人的对象是没有意义的,
//为了不让外界实例化人,修饰成抽象类
abstract class Person{private String name;private int age;public Person(String name, int age) {super();this.name = name;this.age = age;}public Person() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;};}abstract class player extends Person{public player() {super();// TODO Auto-generated constructor stub}public player(String name, int age) {super(name, age);// TODO Auto-generated constructor stub}public abstract void learn(); //public abstract void game(); 
}abstract class coach extends Person{public coach() {super();// TODO Auto-generated constructor stub}public coach(String name, int age) {super(name, age);// TODO Auto-generated constructor stub}public abstract void teach(); }interface speak{public abstract void speadEndlish();
}class pingpong_Player extends player implements speak{public pingpong_Player() {super();// TODO Auto-generated constructor stub}public pingpong_Player(String name, int age) {super(name, age);// TODO Auto-generated constructor stub}@Overridepublic void speadEndlish() {// TODO Auto-generated method stubSystem.out.println("会讲英语");}@Overridepublic void learn() {// TODO Auto-generated method stubSystem.out.println("学打乒乓球");}}class basketball_Player extends player{public basketball_Player() {super();// TODO Auto-generated constructor stub}public basketball_Player(String name, int age) {super(name, age);// TODO Auto-generated constructor stub}@Overridepublic void learn() {// TODO Auto-generated method stubSystem.out.println("学打篮球");}}class pingpong_Coach extends coach implements speak{public pingpong_Coach() {super();// TODO Auto-generated constructor stub}public pingpong_Coach(String name, int age) {super(name, age);// TODO Auto-generated constructor stub}@Overridepublic void teach() {// TODO Auto-generated method stubSystem.out.println("教打乒乓球");}@Overridepublic void speadEndlish() {// TODO Auto-generated method stubSystem.out.println("会讲英语");}}class basketball_Coach extends coach{public basketball_Coach() {super();// TODO Auto-generated constructor stub}public basketball_Coach(String name, int age) {super(name, age);// TODO Auto-generated constructor stub}@Overridepublic void teach() {// TODO Auto-generated method stubSystem.out.println("教打篮球");}}public class testCalc {public static void main(String[] args) {pingpong_Player p1 = new pingpong_Player("马龙",18);System.out.println(p1.getName()+","+p1.getAge());p1.learn();p1.speadEndlish();System.out.println("-------------------");pingpong_Coach p2 =  new pingpong_Coach("刘国强",55);System.out.println(p2.getName()+","+p2.getAge());p2.teach();p2.speadEndlish();System.out.println("-------------------");basketball_Player b1 = new basketball_Player("姚明",20);System.out.println(b1.getName()+","+b1.getAge());b1.learn();System.out.println("-------------------");basketball_Coach b2 = new basketball_Coach("姚明的教练",50);System.out.println(b2.getName()+","+b2.getAge());b2.teach();System.out.println("-------------------");}}

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

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

相关文章

LINUX入门篇【4】开发篇--开发工具vim的使用

前言&#xff1a; 从这一篇开始&#xff0c;我们将正式进入使用LINUX进行写程序和开发的阶段&#xff0c;可以说&#xff0c;由此开始&#xff0c;我们才开始真正去使用LINUX。 介绍工具&#xff1a; 1.LINUX软件包管理器yum&#xff1a; 1.yum的介绍&#xff1a; 在LINUX…

【FPGA】十进制计数器 | 实现 4-bit 2421 十进制计数器 | 有限状态机(FSM)

目录 Ⅰ. 实践说明 0x00 十进制计数器 0x01 有限状态机&#xff08;FSM&#xff09; Ⅱ. 实践部分 0x00 4-bit 2421 十进制计数器 Ⅰ. 实践说明 0x00 十进制计数器 十进制计数器是一种以十进制运算的计数器&#xff0c;从 0 数到 9&#xff0c;然后返回 0 状态。由于它需…

2023NewStarCTF

目录 一、阳光开朗大男孩 二、大怨种 三、2-分析 四、键盘侠 五、滴滴滴 六、Include? 七、medium_sql 八、POP Gadget 九、OtenkiGirl 一、阳光开朗大男孩 1.题目给出了secret.txt和flag.txt两个文件&#xff0c;secret.txt内容如下&#xff1a; 法治自由公正爱国…

玩转硬件之Micro:bit的玩法(五)——垃圾分类

垃圾分类&#xff0c;为了美好的明天 垃圾是我们生活中不可避免的产物&#xff0c;每天都有大量的垃圾被丢弃&#xff0c;如果不加以处理&#xff0c;就会给环境和人类带来严重的危害。 垃圾分类是一种有效的垃圾管理方式&#xff0c;它是指按照一定的标准或规则&#xff0c;将…

计算机组成原理之概述

概述 计组主要讲的是计算机的硬件实现方式。 机器字长 比如8080处理器&#xff0c;如果想处理16位数的整数运算&#xff0c;就需要执行两次。 可见&#xff0c;机器字长会影响到数据的处理速度。 计算机硬件的基本组成 早期的冯诺依曼机 冯诺依曼提出了“存储程序”的概念&…

Socket网络编程

本文主要讲解Socket网络编程。 首先介绍socket&#xff0c;包括TCP和UDP通信过程&#xff1b;然后介绍常用的函数&#xff1b;最后编写client-server例子&#xff0c;并进行测试。 文章目录 Socket介绍TCP通信过程服务器端通信过程&#xff1a;客户端通信过程&#xff1a; UDP通…

智慧工地源码:助力数字建造、智慧建造、安全建造、绿色建造

智慧工地围绕建设过程管理&#xff0c;建设项目与智能生产、科学管理建设项目信息生态系统集成在一起&#xff0c;该数据在虚拟现实环境中&#xff0c;将物联网收集的工程信息用于数据挖掘和分析&#xff0c;提供过程趋势预测和专家计划&#xff0c;实现工程建设的智能化管理&a…

Golang源码分析 | 程序引导过程

环境说明 CentOS Linux release 7.2 (Final&#xff09; go version go1.16.3 linux/amd64 GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7使用gdb查看程序入口 编写一个简单的go程序 // main.go package mainfunc main() {print("Hello world") } 编译go …

假冒 Skype 应用程序网络钓鱼分析

参考链接: https://slowmist.medium.com/fake-skype-app-phishing-analysis-35c1dc8bc515 背景 在Web3世界中&#xff0c;涉及假冒应用程序的网络钓鱼事件相当频繁。慢雾安全团队此前曾发表过分析此类网络钓鱼案例的文章。由于Google Play在中国无法访问&#xff0c;许多用户…

K8S知识点(十)

&#xff08;1&#xff09;Pod详解-启动命令 创建Pod&#xff0c;里面的两个容器都正常运行 &#xff08;2&#xff09;Pod详解-环境变量 &#xff08;3&#xff09;Pod详解-端口设置 &#xff08;4&#xff09;Pod详解-资源配额 修改&#xff1a;memory 不满足条件是不能正常…

Django之三板斧的使用,全局配置文件介绍,request对象方法,pycharm链接数据库,Django链接数据库,ORM的增删改查

【1】三板斧(3个方法)的使用 Httpresponse() 括号内写什么字符串&#xff0c;返回的就是什么字符串返回的是字符串 render(request&#xff0c; 静态文件 ) request是固定的静态文件是写在templates文件夹里面的&#xff0c;如&#xff0c;HTML文件 redirect( 重定向的地址 ) 重…

Hadoop原理,HDFS架构,MapReduce原理

Hadoop原理&#xff0c;HDFS架构&#xff0c;MapReduce原理 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c…

LeetCode刷题总结(一)

文章目录 前言题型排序问题动态规划 前言 本文把刷题过程中的总结记下来&#xff0c;方便未来回顾的时候继续拓展。 题型 排序问题 排序问题的解决方法有很多。对于简单算法来说&#xff0c;最重要的是记住思路&#xff1b;对于高级算法来说&#xff0c;最重要的是记住细节…

利用LangChain实现RAG

检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;结合了搜寻检索生成能力和自然语言处理架构&#xff0c;透过这个架构&#xff0c;模型可以从外部知识库搜寻相关信息&#xff0c;然后使用这些信息来生成response。要完成检索增强生成主要包含四个步骤…

2023亚太杯数学建模A题思路

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料5 最后 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 2023年第十三…

【中间件篇-Redis缓存数据库08】Redis设计、实现、redisobject对象设计、多线程、缓存淘汰算法

Redis的设计、实现 数据结构和内部编码 type命令实际返回的就是当前键的数据结构类型&#xff0c;它们分别是&#xff1a;string(字符串)hash(哈希)、list(列表)、set(集合)、zset (有序集合)&#xff0c;但这些只是Redis对外的数据结构。 实际上每种数据结构都有自己底层的…

【DP】背包问题全解

一.简介 DP&#xff08;动态规划&#xff09;背包问题是一个经典的组合优化问题&#xff0c;通常用来解决资源分配的问题&#xff0c;如货物装载、投资组合优化等。问题的核心思想是在有限的资源约束下&#xff0c;选择一组物品以最大化某种价值指标&#xff0c;通常是总价值或…

【Java 进阶篇】Java与JQuery选择器:解锁前端开发的魔法大门

在前端开发的世界中&#xff0c;选择器是我们与HTML文档进行互动的钥匙&#xff0c;而Java和JQuery则为我们提供了强大的工具&#xff0c;使得前端开发不再是一个艰深的谜题。本篇博客将围绕Java与JQuery选择器展开&#xff0c;深入解析选择器的奥秘&#xff0c;为你打开前端开…

Qt文档阅读笔记-Fetch More Example解析

Fetch More Example这个例子说明了如何在视图模型上添加记录。 这个例子由一个对话框组成&#xff0c;在Directory的输入框中&#xff0c;可输入路径信息。应用程序会载入路径信息的文件信息等。不需要按回车键就能搜索。 当有大量数据时&#xff0c;需要对视图模型进行批量增…

宝塔开心版hostcli的广告去除

首先感谢hostcli把宝塔7.6剥离了&#xff0c;直接安装我这里是缺少pyenv的包。 直接进入正题吧。 定位到页面左下方的广告位于 /www/server/panel/BTPanel/templates/default/layout.html “退出”按钮下方有条线开始去掉 去掉之前的忘了截图了&#xff0c;就这样吧&#xff…