面向对象(Object Oriented),面向对象分析(OOA)、面向对象设计(OOD)、面向对象设计(OOP)
一、对象的概念
对象 就是java类产生的实体
二、面向对象和面向过程的区别
面向过程:最小的程序单元是函数,每个函数负责完成一个功能,用于接收输入数据,函数对输入数据进行处理,然后输出结果数据,整合软件由一个一个的函数组成,主函数依次调用其他函数,普通函数之间可以相互调用,从而实现整个系统功能。也就是面向过程是先分析出解决问题的具体步骤,然后用函数去吧这些步骤一步一步的去实现。
面向对象:把物品抽象成对象,然后给对象赋予属性和方法,通过操作对象的属性和方法来完成我们需要的功能。对象的属性和方法对应着现实世界的物体或者生命的属性和行为,继承对应着父子关系。
三、面向对象的三大核心
面向对象具有继承、封装和多态三个特性
(1)继承
继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法
就比如:经理和普通员工,都是公司的雇员,这时候应该是经理和员工都继承于雇员类,雇员类中可以写通用方法和属性。
雇员类 雇员类里面有两个属性,分别为name和age,一个方法work
public class Employee {
public String name;
public int age;
public void work(){
System.out.println("8点上班,五点下班");
}
}
普通员工类 继承我们的雇员类,用extents
public class Staff extends Employee {
}
public class Testa {
public static void main(String[] args){
Staff zhangsan=new Staff();
zhangsan.work();
zhangsan.name="张三";
zhangsan.age=10;
System.out.println(zhangsan.name);
System.out.println(zhangsan.age);
}
}
通过运行结果我们能够得到,普通员工类中并没有定义任何的属性和方法,但是却得到了name和age属性,work方法,普通员工类继承了雇员类,所以我们的普通员工类就可以拥有了雇员类中的name和age属性,跟work方法。
当然我们不仅可以继承父类的属性和方法,也可以有本类的自己的方法和属性。
经理类 经理类继承雇员类,并添加了自己的属性和方法
public class Manager extends Employee{
public String office ;
public static void rest(){
System.out.println("经理在打盹");
}
}
测试类
@Test
public void test1(){
Manager lisi=new Manager();
lisi.name="李四";
lisi.age=28;
lisi.office="独立办公室";
lisi.work();
lisi.rest();
}
我们能够看到,我们可以给子类添加自己的属性和方法
当我们的经理不在和普通的员工的上下班时间相同时。经理类有了自己的上班时间,这时候就可以重写雇员类中的work方法
这时候我们经理类重写了父类的work方法
public class Manager extends Employee{
public String office ;
public static void rest(){
System.out.println("经理在打盹");
}
@Override
public void work(){
System.out.println("经理9点上班,4点下下班");
}
}
再次运行测试类
我们可以发现经理对象调用的work不在是父类中的了,而是经理类中的work。因为我们子类有了不同于父类的需求,重写了这和方法。
(2)封装
封装:是指一种将抽象性函数式接口的实现细节部分扮装起来、隐藏起来的方法。
封装的好处:封装可以防止该类的代码和数据被外部类定义的代码随机访问。就比如我们一个类封装了一个方法,我们只需要知道这个类的方法名和方法返回值,不需要知道方法内部是怎么去实现的。我们就直接调用该方法,直接使用该方法返回的值就可以了。
public class Testa {
@Test
public void test1(){
System.out.println(Math.max(4.0,5.0));
}
}
就比如上面这个测试中,我们调用了Math类中的max方法,我们只需要把需要的参数传进去,知道会返回什么类型的值就可以了,不需要去了解max里面是怎么实现的。
(3)多态
多态是同一种行为具有多个不同的表现形式或者形态的能力
多态就是同一个接口,使用的不同实例而执行的不同操作。
就比如,一个打印机接口,有两个实现类分别是彩色打印机类和黑白打印机类
这两个类都实现了打印机类中的打印方法,但是这两个类的打印方法的效果是不一样的。
java中多态体现在哪里?
继承是多态的基础
引用多态
父类的引用可以指向本类的对象
父类的引用可以指向子类的对象
方法多态
接着上面的
创建本类对象时,调用的方法为本类方法
创建子类对象时,调用的方法为子类的重写方法或者继承的方法
但是如果我们如上图的代码中的
Father son=new Son();
这个时候如果Son类中有自己独有的方法,不是继承也不是重写而来的
这个时候就不能通过这样的方式去调用独有的方法
(4)继承详解
在继承中,父类的修饰符,如果是private的属性和方法,子类是无法使用的。
在继承规则中,java的继承是单继承的,但是我们可以通过内部类来实现多继承。
public class A {
public String aTest(){
return "我是A类中的a方法";
}
}
public class B {
public String bTest(){
return "我是B类中的b方法";
}
}
public class C{
class E extends A{
public String aTest(){
return super.aTest();
}
}
class D extends B{
public String aTest(){
return super.bTest();
}
}
public void aTest(){
System.out.println(new E().aTest());
}
public void bTest(){
System.out.println(new D().bTest());
}
}
C类中的内部类DE分别继承了BA类
public class test {
@Test
public void t(){
C c=new C();
c.aTest();
c.bTest();
}
}
上面写了一些方法的重写,在这里补充一下重写。我们对父类进行重写,这时候子类默认调用的是重写后的方法。重写要注意的是,方法的返回值类型,方法名,以及参数类型和个数都要与父类的方法相同,也就是说
如果父类是 public String a(String b){}
子类重写必须是 public String a(String b)
这里的public是访问控制符,子类重写方法时,访问控制符的范围是大于等于父类的方法的访问控制符的
访问控制符的范围大小
public>protected>default>private
至于形参中是一个String类型的参数就可以,至于叫 b,c或者d都无所谓,这就涉及到其他部分去了。这里涉及到,java形参的传递是属于值传递,形参接到的值,是属于复制品,形参修改了并不会修改原来的实参。
方法的签名:方法名+方法参数 比如上面的 a(String b)叫作方法签名
有方法重写,还有方法重载
这两个来区分一下
重写:相对于继承,子类对父类的方法进行修改
重载:是在同一个类中有多个方法名相同,但是返回值或者参数不同
上面有重写的过程,这里来看看重载
public class test {
public void a(){
System.out.println("a");
}
public void a(String a){
}
public void a(String a,String b){
}
public String a(int b){
return "a";
}
}
四、关键词
final关键词
第一、final关键词如果修饰类,则该类不允许被继承
我们把A类定为final类
public final class A {
}
B类再去继承A类的时候就会报错,提示不能继承final类
第二、final修饰的方法允许被重写
public class A {
public final void a(){
}
}
再去重写final方法时,也会报错,提示移除final
第三、final修饰变量,该变量只能赋值一次,并且声明的时候必须赋值
super关键词
super关键词在对象内部使用,代表的是父类对象
访问父类的属性super.name
访问父类的方法super.work()
当一个子类的构造方法没有显示的调用父类的构造方法时,虚拟机默认调用的是父类的无参构造,这里就隐式的使用了super关键字
如果子类的构造方法显示调用了父类的构造方法,super必须放在第一行
不放在第一行报错图片
上面讲过子类没有显示调用父类的构造函数是,默认会去调用父类的无参构造
但是如果父类没有无参构造的话,就会编译出错。
虚拟机在一个类编译的时候,如果这个类没有编写任何的构造函数,会默认的加入一个无参构造方法。但是如果你这个类中已经有了有参构造方法,虚拟机认为你有构造方法了,就不会再加入无参构造了。你这时候如果再去调用无参构造的话,是找不到,是会报错的。
this关键词
有super父类对象,当然有this当前对象
this关键字代表的是当前对象
this.属性 调用当前对象的属性
this.方法 调用当前对象的方法
五、内部类
上面有用到内部类,这里比较全面的讲讲
内部类见名知意那就是定义在类里面的类,包含在内部类的类,叫作外部类
首先我们要知道一个东西的出现肯定是有原因的,我们见到一个新东西,就得考虑,为什么会有这个东西,这个东西是的产生是为了解决哪些问题的。
呐为什么会有内部类产生呐?
内部类的作用是为了更好的封装,把内部类隐藏在外部类里面,不允许其他类访问该内部类。同时内部类可以访问外部类所有的属性,包括私有的数据。这样使用起来更方便。
内部类又分为多种
成员内部类
静态内部类
方法内部类
匿名内部类
成员内部类
public class A {
class B{
}
}
静态内部类
public class A {
static class B{
}
}
方法内部类
public class A {
public void test(){
class B{
}
}
}
方法内部类,只在定义方法内部类的那个方法有效
匿名内部类
public class A {
public void test(){
new Inner(){
};
}
}
本文属于自己参考文章和结合自己的总结来学习和巩固Java基础
参考文章:https://github.com/h2pl/Java-Tutorial/blob/master/docs/java/basic/1%E3%80%81%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E5%9F%BA%E7%A1%80.md