当前位置: 首页 > news >正文

【Java学习】【Java基础】--第1篇:入门Java和对面向对象的理解

一、浅谈为何学习Java

24年本科毕业,从事电气工程师的岗位至今,工作内容愈发让自己觉得无聊。工作中接触到web开发的同事,便对此感兴趣。在学习过程中也验证了这个点,抛开之后是否能靠学这个转行不谈,投入到学习编程的过程中,能让我忘记时间、忘记疲惫,全身心地投入到其中。这也是我取名JustForFun的原因,希望在此过程中能收获快乐,并且能坚持下去。

二、对面向对象的理解

Java基础已经基本学的差不多了,个人觉得面向对象较为重要,并且有几个点不是很好理解,记录一下自己的理解,深入学习后继续更正

面向对象编程(Object-Oriented Programming,简称OOP)是一种编程思想,将具有相同或类似属性、方法的对象抽象为一个类。面向对象有3个核心概念:封装、继承、多态。

1. 封装

封装比较好理解,将程序的核心功能封装在一个“黑匣子”里面,只给用户暴露使用的接口。
假设有这样一个场景,我们要定义两个人,他们有名字、年龄,并且会做自我介绍,按照面向过程的思路,应该这样实现:

public class Main {public static void main(String[] args) {// person1String p1Name = "小明";int p1Age = 18;// person2String p2Name = "小红";int p2Age = 20;introduce(p1Name, p1Age); // 我叫小明, 我今年18岁。introduce(p2Name, p2Age); // 我叫小红, 我今年20岁。}public static void introduce(String name, int age) {System.out.println("我叫" + name + ", 我今年" + age + "岁。");}}

但是这样,又会暴露一些问题:
1.当我要定义再多一点人时,我需要重复定义新的name和age,每新增一个人,我都需要写一遍introduce(name, age)
2.introduce()这个方法应该是属于person的,因为只有人会做自我介绍(不考虑人工智能之类的),但如果我定义一个dogName = "旺财"; dogAge = 3,我同样可以调用introduce(),让一只狗做自我介绍,这明显是不对的。
在这种情况下,因为所有的人都有名字、年龄这两个属性,都有自我介绍这个行为或者方法,所以我可以将人抽象为一个类Person

class Person {public String name;public int age;Person() {}Person(String name, int age) {this.name = name;this.age = age;}public void introduce() {System.out.println("我叫" + name + ", 我今年" + age + "岁。");}
}

那么对于以上问题,我们可以这样解决:

public class Main {public static void main(String[] args) {Person[] persons = {new Person("小明", 18),new Person("小红", 20),new Person("小花", 18),new Person("小李", 19)};persons[3].age = 65536;for (Person p: persons) {p.introduce();}/*我叫小明, 我今年18岁。我叫小红, 我今年20岁。我叫小花, 我今年18岁。我叫小李, 我今年65536岁。*/}}

我不需要每次新增一个人,都去写一遍introduce()方法。同样的,由于introduce()被封装到Person类里了,其他的小狗小猫就无法调用这个函数了。
但是还存在问题,类里的属性是public的,意味着用户可以随意对这些属性进行更改,可能就会出现一个人65536岁的可能,这是不符合逻辑的。所以封装另一个思想就是只保留有限的接口给用户,而把内部复杂、核心的内容给隐藏起来:

class Person {private String name; // 私有化private int age; // 私有化Person() {}Person(String name, int age) {this.name = name;setAge(age);}public void introduce() {System.out.println("我叫" + name + ", 我今年" + 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 >= 0 && age <= 130)? age: 0;}
}public class Main {public static void main(String[] args) {Person[] persons = {new Person("小明", 18),new Person("小红", 20),new Person("小花", 18),new Person("小李", 19)};// persons[3].age = 65536; 这句话编译已经无法通过了persons[3].setAge(65536);for (Person p: persons) {p.introduce();}/*我叫小明, 我今年18岁。我叫小红, 我今年20岁。我叫小花, 我今年18岁。我叫小李, 我今年0岁。*/}}

我们可以根据用户的输入,在内部通过我们自己的规则进行处理,而非把所有权限暴露给用户,让用户可以随意更改

2.继承

当我们需要使用一个共同的类,但是又要有所特点时,就要用到继承。还是以Person类举例,根据职业,我们可以将人分为教师、学生等等,虽然都属于人这个大类,但每个小类都有自己不同之处。教师、学生都继承于人,拥有人的共同特点,但又因为职业不同,拥有属于自己的特点:

class Teacher extends Person {Teacher() {}Teacher(String name, int age) {super(name, age);}public void teach() {System.out.println(super.getName() + "正在教书");}
}class Student extends Person {Student() {}Student(String name, int age) {super(name, age);}public void study() {System.out.println(super.getName() + "正在学习");}
}public class Main {public static void main(String[] args) {Teacher teacher = new Teacher("王老师", 29);Student student = new Student("小明", 18);// 都能够调用父类的public方法teacher.introduce(); // 我叫王老师, 我今年29岁。student.introduce(); // 我叫小明, 我今年18岁。// 调用自己的方法teacher.teach(); // 王老师正在教书student.study(); // 小明正在学习}}

3.多态

个人人为多态是面向对象最不好理解,也是最有趣的点,感觉多态就是面向对象最核心的概念。多态按照解释叫做:同一个行为在不同对象上表现出不同的形态。父类Person具有introduce()方法,子类TeacherStudent都可以直接调用,进行自我介绍。但这样的自我介绍又太干巴了,希望子类在介绍自己的同时,可以说明一下自己的职业,此时就需要对继承于父类的方法进行重写

class Teacher extends Person {Teacher() {}Teacher(String name, int age) {super(name, age);}public void teach() {System.out.println(super.getName() + "正在教书");}// 重写父类方法@Overridepublic void introduce() {System.out.println("我叫" + super.getName() + ", 我今年" + super.getAge() + "岁, 我是一名老师。");}
}class Student extends Person {Student() {}Student(String name, int age) {super(name, age);}public void study() {System.out.println(super.getName() + "正在学习");}// 重写父类方法@Overridepublic void introduce() {System.out.println("我叫" + super.getName() + ", 我今年" + super.getAge() + "岁, 我是一名学生。");}
}public class Main {public static void main(String[] args) {Teacher teacher = new Teacher("王老师", 29);Student student = new Student("小明", 18);teacher.introduce(); // 我叫王老师, 我今年29岁, 我是一名老师。student.introduce(); // 我叫小明, 我今年18岁, 我是一名学生。}}

同一个行为introduce()在不同对象上表现出不同的形态,这就是多态。多态有个很妙的设定,叫做父类对象指向子类的引用,Person person = new Student()。还是以学生和老师为例,我现在建立一个函数introduceYourself(obj),希望传入里面的obj对象能做一个自我介绍,那这个obj对象,应该是老师,还是学生呢?如果我写成introduceYourself(Teacher teacher)的话,所有老师都可以传入其中进行自我介绍,但是学生呢?除了老师以外的Person呢?因为对象类型不同,无法传入函数。同样的,这个obj对象我指明是学生的话,也会出现同样的情况。
所以最好的方法应该将对象类型指明为他们的父类Person

public class Main {public static void main(String[] args) {Teacher teacher = new Teacher("王老师", 29);Student student = new Student("小明", 18);introduceYourself(teacher); // 我叫王老师, 我今年29岁, 我是一名老师。introduceYourself(student); // 我叫小明, 我今年18岁, 我是一名学生。}public static void introduceYourself(Person person) {person.introduce();}}

父类对象Person,指向了子类Teacher和Student的引用,而由于他们都具有同样的introduce()方法,并且子类已经进行重写,此时父类会调用子类的方法,从而实现同一行为的不同表现。(静态方法不适用该情况,静态方法仍会调用父类的方法,具体原理还不懂)

三、总结

第一次写这么多内容,可能会有很多理解是错误或者不全面的,后面再做订正。

http://www.hskmm.com/?act=detail&tid=28203

相关文章:

  • solutions
  • 技术面:Spring (事务传播机制、事务失效的原因、BeanFactory和FactoryBean的关系)
  • 安装与配置MySQL 8 on Ubuntu,包括权限授予、数据库备份及远程连接
  • 04-最简单的字符设备驱动
  • 完整教程:手机可视化方案(针对浓度识别)
  • AI元人文系列文章:决策范式与无为而治
  • SAP导入证书
  • Kubernetes存储卷:保障有状态应用的数据持久化
  • MySQL的查询操作语法要点
  • 华为链路聚合配置
  • 手机adb 调试自己
  • 离线安装 mysql
  • what is a good parent
  • 2025 年公共/商场/学校/地铁/电影院/会所/机场/卫生间隔断厂家选购指南:优质厂商推荐与实用选择策略
  • 为什么不该用 Double 表示金额及解决方案
  • Windows开发环境安装备忘录
  • Vue.use(Vuex)
  • [Gym-100343E]Convex Permutominoes 题解
  • MyBatis 中的动态 SQL 的相关使用方法(Javaee/MyBatis) - 教程
  • 网络优化问题
  • Java环境安装备忘录
  • 深入解析:【Spring MVC终极指南】一文掌握请求处理与响应!从Servlet原生方式到SpringMVC高效优雅写法
  • foobar2000 v2.25.2 汉化版
  • 比特币地址投毒攻击深度剖析
  • 为什么大家都爱用微擎?这几点真的太香了
  • 【JS逆向百例】某坤行 1101,雪球 1038,新 acw_sc__v2 逆向分析
  • JAVA 的模板方法模式解析
  • 《构建之法-现代软件工程》 -阅读和提问作业1
  • 计算机视觉与AI在人体成分分析中的技术突破
  • 2024-网鼎杯web-PyBlockly