java基础学习day07(面向对象、static关键词、this关键词、super关键词)
第一章 面向对象
1.1 什么是面向对象?
1.1.1 面向对象和面向过程的区别
1.面向对象:就拿人开车来说,在人开车这个实例中,人和车就是两个对象,人负责开车,车负责被开,在这里我们只看车子能不能开动,只要具备车有开的的功能,然后人有会开车的功能,车子就能开动,这里不用去管车子如何开动,人如何去开车的。
面相对象是解决问题的一种方式,它针对一些简单的问题有一些大材小用,但是它对一些复杂的问题可以变得很轻松,面向对象是从宏观上把控事务的整体走向。
2.面向过程:还是拿人开车来说,在人开车这个实例中,涉及到很多个过程,比如说人如何去开车啊,设计到发动车子的过程,放手刹啊,挂档啊,车又是如何发动的。
面向过程是解决问题的另一种方法,他针对一些简单的问题可以很轻松的解决,但是一些复杂的问题就会很繁琐,面向过程是微观上解决问题的方法。
3.区别联系:面对对象和面对过程不是相互独立的而是相互依存的,当你通过面向对象去解决一个问题的时候,在你创建对象的时候,还是面向过程去执行解决的。在编码过程中而言,存在一个需求,先从宏观上整体看待需求,再从微观上去实际编码解决问题。
1.1.2 对象
1、什么是对象?
在java中万事万物都是对象。显示在生活中的所有的东西都是一个个的对象。每个对象都有他自己的功能,我们通过这一个个的对象可以来完成我们需要完成的相对应的需求,它减少了使用者的使用复杂度,提高了被使用者的安全度。
2、对象如何产生?
在咱们目前学习的过程中,咱们只是见过类和方法。创建对象其实是在创建类的过程中通过创建一个另外的类的对象,通过调用另一个类中的变量和方法来完成自己的需求,从而使得你遇见相同的问题不用多次编写代码来解决,直接通过该对象去调用发法变量去完成你要的需求的这么一个过程,所以类和对象必定会存在关系。
3.类和对象的关系
在java中:类是class修饰的一个类,它可以产生很多个对象,而对象则是基于类的一个实例化的表现形式。
类的产生是依赖于对象的,类是将对象中具有相同特征或者行为抽取出来归为一类,而对象的产生也是依赖于类的,如果没有类的话是无法产生该类的对象的,类是对于对象的抽像,对象是类的具象化的表现形式。
1.2 如何编写类和对象
1.2.1 如何编写类?
看如下代码:
public class FoundClass {
//写出该类所具有的外在的表现形式(即成员变量)
String name = "张三";
int num = 8;
char ch = 'A';
//编写出该类所具有的内在功能即java中的方法
public void write(){
System.out.println("好好编写代码");
}
public void read(){
System.out.println("读好别人编写的代码");
}
}
tips:现在我们在去编写代码的时候,要习惯将变量写成成员变量;我们现在再去写方法的时候先不要去加static,后续过程主要去讲这个static关键字的时候我们在去看为什么。
分析代码:1.该代码中,成员变量表示为该类所具有的一些外在表现形式,以后都通过这样的方式去定义;
2.该代码中,方法表示为该类所具备的内在功能,即该类能干什么,它能完成什么;
3.不管是成员变量还是方法统一不用static来修饰。
1.2.2 如何编写对象?
在java中是通过new关键词来产生一个类的对象的。
看如下代码:
public class FoundObject {
public static void main(String[] args) {
//创建一个FoundClass对象
FoundClass object = new FoundClass();
//通过变量名.变量或变量名.方法来调用类的变量和方法
String name1 = object.name;
System.out.println(name1);
object.write();
}
}
注意事项:1.创建对象一定是通过new关键词来创建的;
2.创建对象的基本写法:类名 变量名=new 类名();
new关键词的作用
我们基本数据类型的赋值很简单,直接赋值就好了,可是对于引用数据类型来说,我们给一个引用数据类型的变量赋值时都是要通过new关键词来赋值的,可以说new这个关键词是极其重要的。
new关键词有三个作用:
- 看到new关键词,那么电脑会立即在堆内存中开辟空间存储类中的成员变量和方法;
- 看到new关键词,就会给成员变量赋给它的初始值;
- new关键词一出现,栈内存中存储的局部变量会指向引用堆内存中存储的成员变量或者是方法,将堆内存中存放的方法或者成员变量的地址值赋值给栈内存中的局部变量。
1.3 构造器
在java中 ,构造器就是用来产生对象的特殊方法,将这种特殊的方法称为构造器。
1.3.1如何声明构造器?
看如下代码:
public class FoundConstructor {
int num = 8;
String name = "李四";
//创建一个该类构造器
public FoundConstructor(){
}
public void eat(){
System.out.println("该吃饭了");
}
}
tip:1.构造器是一个特殊的方法,在声明是,方法名一定要和类名一致,首字母一定要大写;
2.构造器在声明的时候返回值不需要写,即不用写void也不用写返回值类型;
3.在构造器中的最后一行不需要return值。
1.3.2 构造器的注意事项
1.默认的构造器
在java中,如果类中没有一个构造器的生命,那么java会自动给他填充一个空参数的构造器。
2.带参数的构造器
看如下代码:
public class FoundConstructor01 {
int num ;
String name;
int weight;
public FoundConstructor01(){
}
public FoundConstructor01(int num1){
num = num1;
}
public void write(){
System.out.println("好好写代码");
}
}
tips:
- 在我们声明了一个带有参数的构造器后,如果我们将默认存在的无参的构造器写出来了,那么它会存在,如果我们没有声明这个默认的构造器,那么它就不会存在了;
- 构造器也能重载。
3.创建对象调用有参构造器
看如下代码:
public class FoundConstructor01 {
int num ;
String name;
int weight;
public FoundConstructor01(){
}
public FoundConstructor01(int num1){
num = num1;
}
public FoundConstructor01(int num2,String name1,int weight1){
num = num2;
name = name1;
weight = weight1;
}
public void write(){
System.out.println("好好写代码");
}
}
public class FoundConstructorText {
public static void main(String[] args) {
FoundConstructor01 f = new FoundConstructor01();
System.out.println(f.num);//输出结果是0;
FoundConstructor01 d = new FoundConstructor01(6);
System.out.println(d.num);//输出结果是6;
FoundConstructor01 g = new FoundConstructor01(8,"张三",130);
System.out.println(g.num+","+g.name+","+g.weight);
//输出结果是8,张三,130;
}
}
qtips:创建对象的方式就和方法与方法之间的调用类似,主要看的就是参数是否能够对上,创建对象时()内的实际 参数与构造器中的形式参数匹配到了即执行。
1.3.3 this关键词
this关键词一共有两种用法,为:this.和this()。
1.this.
this.代表的是当前对象的,也就是说谁在调用那么这个谁就是当前对象。
可以省略
this.大部分时候可以省略的;
看如下代码:
public class UseThis {
String name;
int num;
int height;
public UseThis(){
this.write();
}
public UseThis(String yname){
name = yname;
System.out.println(this.name);
}
public void write(){
System.out.println("好好写代码");
}
}
public class UseThisText {
public static void main(String[] args) {
UseThis a = new UseThis();
//输出好好写代码;
UseThis a1 = new UseThis("张三");
//输出张三;
}
}
如上述代码中this.就可以省略掉不写。
不可省略
当出现了两个或多个同名变量的时候这个this.是不可以省略的,此时this.是用来区分同名变量的
看如下代码:
public class UseThis01{
String name;
int num;
int height;
public UseThis01(){
this.write();
}
public UseThis01(String name){
this.name = name;
this.write();
}
public void write(){
System.out.println(this.name+"好好写代码");
}
}
public class UseThis01Text {
public static void main(String[] args) {
UseThis01 b = new UseThis01();
//输出结果是null好好写代码;
UseThis01 b1 = new UseThis01("张三");
//输出结果是张三好好写代码;
}
}
上述情况下this.不可以省略。
通常情况下我们只要记住要区分同名变量是this.是不可以省略的那么其他情况下一般都是可以省略就行了。
2.this()
this()是用来实现构造器之间的相互调用的。
看如下代码:
public class UseThis02 {
String name;
int num;
int height;
public UseThis02(){
this("张三");
}
public UseThis02(String name){
this.name = name;
this.read();
}
public void read(){
System.out.println(this.name+"好好读别人的代码");
}
}
public class UseThis02Text {
public static void main(String[] args) {
UseThis02 c = new UseThis02();
//输出结果是张三好好都别人的代码;
}
}
注意事项:
- this()是用来实现构造器之间的相互调用的;
- 其他不同的方法中是不可以使用this()的,它只能在构造器中使用;
- this()在构造器之间进行调用的时候,必须保证this()在构造器的第一行语句。
1.4 static关键词
static的意思是静态的共享的。
1.4.1 如何使用static关键词?
1.在static中使用非static修饰的
方法一:看如下代码:
public class UseStatic {
static int num = 78;
public static void main(String[] args) {
System.out.println(num);
//输出结果为78
}
}
在static修饰的上述方法中访问未被static修饰的num变量时,在num的类型变量名前面加上static,这样可以实现访问。但是这种方法我们不推荐使用。
方法二:看如下代码:
public class UseStatic01 {
int num = 78;
public static void main(String[] args) {
//创建一个对象,通过对象.num去访问这个变量
UseStatic01 num1 = new UseStatic01();
System.out.println(num1.num);
//输出结果是78;
}
}
创建当前类的对象,通过对象.方法或者变量访问非静态内容。
2.在非static中使用static修饰的
看如下代码:
public class UseStatic02 {
static int num = 78;
public static void main(String[] args) {
UseStatic02 t = new UseStatic02();
t.method();
}
public void method(){
System.out.println(num*2);
//输出结果是156;
}
}
- 在一个类中非静态内容访问静态内容直接通过变量名或者是方法名称就可以访问了。
再看如下代码:
public class UseStatic02 {
static int num = 78;
public static void main(String[] args) {
UseStatic02 t = new UseStatic02();
t.method();
}
public void method(){
fun();
}
public static void fun(){
System.out.println(num*3);
}
}
public class UseStatic03 {
public static void main(String[] args) {
UseStatic02.fun();
//输出结果是234;
System.out.println(UseStatic02.num);
//输出结果是78;
}
}
注意事项:
- 在其他类中访问static修饰的内容时可以直接通过类名.变量名或者类名.方法名()来访问;
- 静态内容再其他类中访问的时候可以直接通过类名来访问;也可以通过创建类的对象来访问,但是我们不推荐这种方法。
3.static的注意事项
- static修饰的内容是属于类的,类被加载,静态内容就被加载到内存中了;
- 而非static修饰的内容是属于对象的,只有创建了对象,它才能被调用;
- 类信息是先于对象存在的,创建对象时类一定被加载到了内存中,但是创建了类,对象不一定加载在内存中。
1.5 继承
继承通俗理解为子承父业,它描述的是类和类之间的关系,编写类的时候,我们发现类和类之间是可以存在父子关 系的。通过 extends 来描述这种继承关系。 子类 extends 父类。
1.5.1 继承是如何表现的?
看如下代码:
public class Father {
int weight;
String name;
int age;
public Father(){
System.out.println("父亲的无参构造器");
}
public Father(int weight){
this.weight = weight;
System.out.println("父亲的有参构造器");
}
public void scold(){
System.out.println("父亲责骂儿子");
}
}
public class Son extends Father {
int id;
public Son(){
System.out.println("儿子类的无参构造器");
}
public Son(int id){
this.id = id;
System.out.println("儿子类的有参构造器");
}
public void play(int id){
this.id = id;
System.out.println("天天就知道玩");
}
}
public class SonText {
public static void main(String[] args) {
Son d = new Son();
d.weight = 130;
d.name = "张三";
d.age = 18;
int id = 20140004;
}
}
程序分析:
- 虽然Son这个类它不存在weight、age、name和scold属性,但是Father类中是存在的,也就是说我们通过extends将Father类的这些属性给了Son类。
- 在java中一旦发生继承关系之后,子类就会拥有父类中的属性以及方法。子类无需自己再去声明。
注意事项:
- 子类继承父类我们可以提高程序的复用性,A类继承B类,A类继承C类,这样下去会导致对于A类而言它的内部的功能是及其强大,或者是说它拥有了更多的资源和能力;
- 在java中只支持单继承。导致复用性虽然有,但是不是特别高。针对这个问题,Java采用的策略称之为单继承、多实现;
- 在java中一个类只有一次继承机会,如果不能完全确定最好不要用。
1.5.2 super关键词
super关键词一共有两种用法:分别为super.和super()。
1.super.的用法
super.表示当前对象的父类的对象的。
可省略
看如下代码:
public class Father {
int weight;
String name;
int age;
public Father(){
}
public Father(int weight){
this.weight = weight;
System.out.println("父亲的有参构造器");
}
public void scold(){
System.out.println("父亲责骂儿子");
}
}
public class Son extends Father {
int id;
public Son(){
System.out.println(super.weight+","+super.age+","+super.name);
super.scold();
//输出结果是0,0,null 父亲责骂儿子;
}
public Son(int id){
this.id = id;
System.out.println("儿子类的有参构造器");
}
public void play(int id){
this.id = id;
System.out.println("天天就知道玩");
}
}
public class SonText {
public static void main(String[] args) {
Son d = new Son();
}
}
如上述代码所示,这里的super.是可以省略的。
不可省略
看如下代码:
public class Father {
int weight = 180;
String name;
int age;
public Father(){
}
public Father(int weight){
this.weight = weight;
System.out.println("父亲的有参构造器");
}
public void scold(){
System.out.println("父亲责骂儿子");
}
}
public class Son extends Father {
int id;
int weight = 130;
public Son(){
System.out.println(super.weight+","+super.age+","+super.name);
System.out.println(weight);
//输出结果是180,0,null 130;
}
public Son(int id){
this.id = id;
System.out.println("儿子类的有参构造器");
}
public void play(int id){
this.id = id;
System.out.println("天天就知道玩");
}
}
public class SonText {
public static void main(String[] args) {
Son d = new Son();
}
}
- 当父类和子类出现了同名的变量、同名方法时,为了能够区别父类和子类的同名变量或者是同名方法,此时super一定不能省略。如果省略了,默认情况下省略的是this.。子类中访问到的一定是子类自己的变量或者是方法。
2.super()的用法
看如下代码:
public class Father {
int weight = 180;
String name;
int age;
public Father(){
System.out.println("父亲的无参构造器");
}
public Father(int weight){
this.weight = weight;
System.out.println("父亲的有参构造器");
}
public void scold(){
System.out.println("父亲责骂儿子");
}
}
public class Son extends Father {
int id;
int weight = 130;
public Son(){
System.out.println("儿子类的无参构造器");
}
public Son(int id){
this.id = id;
System.out.println("儿子类的有参构造器");
}
public void play(int id){
this.id = id;
System.out.println("天天就知道玩");
}
}
public class SonText {
public static void main(String[] args) {
Son d = new Son();
}
}
上述代码的输出结果是:父类的无参构造器 儿子类的无参构造器
注意事项:
- 创建子类对象时之所以父类构造器被先执行原因是由于在子类构造器的第一行存在一个 super();
- super()指向的是父类的无参构造器(任何一类中都系统默认添加一个无参构造器),被调用之后会在内存中创建一个父类对象;
- 子类不能平白无故的创建,必须要保证父类存在,子类才能被创建出来。
- super()就是用来调用父类的构造器的。
3.super()调用时机
看如下代码:
public class Person {
String name;
public Person() {
System.out.println("person 无参构造器");
}
public Person(String name) {
System.out.println("person 带参构造器");
}
}
public class Student extends Person {
int id;//学号
public Student() {
this(12);
System.out.println("student 空can构造器");
}
public Student(int id) {
super("123");
this.id = id;
System.out.println("student 有can构造器");
}
}
public class Text {
public static void main(String[] args) {
Student stu = new Student();
}
}
上述代码的输出结果是:person 带参构造器 student 有can构造器 student 空can构造器
注意事项:
- 对于所有的子类而言。在子类的构造器的第一行都存在super();
- this()和super()不能共存。当构造器中存在super,就不能显式编写this();如果构造器中存在 this(),那么构造器中的默认super()空构造器就不存在了;
- 父类的构造器只会被调用一次。