java的面向对象
面向对象
-
物以类聚,分类的思维模式,思考问题首先解决问题需要哪些分类,然后对这些分类进行单独思考,最后对各个分类下的过程进行思考。
-
对于描述复杂问题的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象来分析整个系统,但是,具体的微观操作,仍然需要使用面向过程的思路去处理。
-
以类的方式组织代码,以对象的组织(封装)数组
三大特性:
封装
继承
多态
类内包含两部分: 属性和方法。
对象是类的实例化,
语法:类名 对象名=new 类名();
默认情况下对象的属性都有默认值,int类型为零,String类型为null等等
构造器 (构造方法)
- new对象本质就是调用构造器。(无返回值)
- 构造器一般用来初始化值。
构造器在生成对象时默认调用,分为有参和无参,当有参存在时,无参必须显示定义(写出来),当我们有参无参均未写时,系统自动添加无参构造(默认隐藏)。构造器只能是public修饰,因为在main()中定义对象时选需要调用构造器。
使用 this.属性名 用来访问调用的对象的属性。有多个属性时可以重载多个构造器。
在IDEA中使用Alt+Insert可以选择construct可以快速创建构造器。
eg:
package Creat;//类一
public class Creat01 {
public String name;
int age;
public Creat01()
{
this.age=10;
this.name="待输入";
}
public Creat01(String name) {//一个参数
this.name = name;
}
public Creat01(String name, int age) {//两个参数
this.name = name;
this.age = age;
}
}
import Creat.Creat01;
public class Application { //类二
public static void main(String[] args) {
Creat01 xiaoming=new Creat01();//创建时调用无参构造器
Creat01 xiaohong=new Creat01("xiaohong");//创建时调用一个参数的构造器
Creat01 xiaohei=new Creat01("xiaohei",18);//创建时调用两个参数的构造器
System.out.println(xiaoming.name);
System.out.println(xiaohong.name);
System.out.println(xiaohei.name);
}
}
注:
main方法在栈里,main()结束程序也就结束了,
static静态方法区,类调用的时候和类一起加载。存放在堆中。
引用类型在没有赋值的情况下默认为null
封装:
我们的程序设计要追求 高内聚,低耦合,高内聚就是指类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅仅暴露少量的方法给外部用
属性私有:get/set
可以理解为不再对属性直接修改,将属性赋予私有属性,通过定义方法对属性修改。get为得到属性,set为修改属性。
在IDEA中,Alt+Insert可以自动生成get和set对属性进行修改。(getter setter)
在定义类中属性(变量),方法时,一般使用public,private,protected修饰,在这之中只有public作用下可以在main()方法中直接访问。
public:可以被继承,可以直接在main()中通过对像直接访问和修改,公开对外部可见.
private:不可被继承,仅对类内部可见,可通过方法进行修改和访问
protected:可被继承,对包和所有子类可见,可通过方法修改访问
default:不作任何修饰时系统默认为此修饰。可被继承,对类内部和同一包內可见,可通过方法修改访问。
继承:类之间的关系
继承的本质是对某一批类的抽象。
extends的意思是扩展,子类是父类的扩展,子类会继承父类的属性和方法,private属性下的东西无法继承,默认下的属性default。
super关键字与this类似,super指代的是父类中所继承的与子类中同名的属性区分方法。例如super.name;指代的是继承自父类的name属性,this.name指代的是子类原本的那么属性,他们可能同名但是并非同一个值。同样的super();是调用父类的构造器(默认情况下,隐式的写在子类构造器的第一行,当我们人为写出时只能放在第一行,否则报错),this();指的是子类构造器,方法也是同理的。
tip:
对继承自父类的方法重写时,重写的方法的方法权限不能小于父类的权限,例如:父类方法的权限级为public,子类重写的方法不能是private的权限级下的。
this();和super();不能同时在子类构造器中显式的写出,因为两者都要求要写在第一行,否则会报错,因此直接不写出即可,自动隐式生成。父类没有无参构造。子类生成时也会报错!除非写出super(参数);
super只能出现在子类的构造器或者方法中。只有继承才可以使用。
注:
java中只有单继承,没有多继承。在java中所有类默认继承object类。
在IDEA中Ctrl+H可以查看继承的分级情况。
使用final修饰的类不能再被继承
public final class father{ //不能被继承
}
final修饰的方法不能被重写,
final修饰的变量只能进行一次赋值
eg:
//父类
package Inherit;
public class Inherit01 {
String name="father";//default属性下的变量
public int age=52; //public 下的
private double high=170.0; //private下的不能被继承
protected double weight=69;//protected
public Inherit01()
{
name="Tom";
age=53;
high=171;
weight=68;
}
}
//子类
package Inherit;
public class Inherit02 extends Inherit01{
public Inherit02 ()
{
// super();//调用父类构造器
}
String name="son";
int age=21;
double high=181.0;
double weight=70;
public void test01(String name){ //如果在参数中定义的有同名变量,那么单写变量名指代的是参数中的变量
//想要指代自己定义的需要使用this指针
System.out.println("自己定义的:"+this.name+" "+age+" "+high+" "+weight);
System.out.println("继承获得的:"+super.name+" "+super.age+" "+super.weight);
//私有private下的high未能得到继承
System.out.println("传入参数的同名变量:"+name);
}
}
//应用
import Inherit.Inherit02;
public class Application {
public static void main(String[] args) {
//继承的测试代码
Inherit02 inherit02=new Inherit02();
inherit02.test01("传入的name");
}
}
重写:
重写必须要有继承关系,是子类对父类方法的重写。
- 方法名必须相同
- 参数列表必须相同
- 修饰符的范围只能扩大不能缩小 public>protected>default>private
- 抛出异常的范围只能缩小不能扩大
不能是static的静态函数
子类和父类的方法名一致,但是方法体不同。
为什么要重写?
父类的方法子类不一定需要,或者不一定满足需求
IDEA中的重写快捷键: Alt+insert----->override
静态方法的调用中,仅仅和左边的定义有关。例如:A类继承自B类。若两者都含有静态方法test()
A a=new A();
B b=new A(); //父类的引用指向子类的,仅可调用父类中有的方法。
a.test(); //调用的是A中写的test()
b.test(); //调用的时B中 的方法test()
若不是静态方法,而是普通的方法,则test在A中的定义直接实现了test方法的重写。
不能重写的方法:
- static 方法,属于类的,不属于实例
- final 常量的,在常量池
- private 方法
多态:
同一方法根据发送对象不同而采取不同的欣行为方式
一个对象的实际类型是确定的,但是可以指向对象的引用类型(父类,有关系的类)有很多。
多态是方法的多态,属性没有多态
存在条件:继承关系,方法需要重写,父类的引用指向子类的对象 father f1=new son();
instanceof:
使用比较x和Y的关系,x为对象,Y为一个类。
如果X和Y存在父子关系则可以通过编译,否则无法通过编译,比较返回结果的true或false
如果对象X属于类Y或者其父类产生的对象则为true,否则为false
要进行强制的了类型转换:
子类转换为父类可能丢失自己本身的一些方法。
只能是父类引用指向子类的对象。
父类转换为子类需要强制转换,通过强制的转换,通过降级或升级使其能够调用它本身的一些其他方法
((Student)object).方法(); //强制转换的方法