java学习笔记

java数据类型的转换

Java中可以进行不同数据类型的加减乘除运算吗?是可以的。在算术运算符中已经体验过如果两个整数(int)相除会去掉小数部分。如果需要保留小数部分,可以让除数或者被除数变为double类型的(5变为5.0)。其实Java是自动的将int的那个数变为了double类型了也就是Java自动的将整数变为了浮点数。例如5/2.0 其实是5.0/2.0

1、 自动类型转换(也叫隐式类型转换)

    可以将一个数赋值给更大数值范围的变量,例如可以经byte 变量赋值给short变量可以将short变量赋值给int变量可以将int变量赋值给long变量。

Java内部其实做了工作就是自动将数值进行了类型提升,就叫做自动类型转换(也叫隐式类型转换)

byte b = 1; //00000001

       short s = b;  //00000000 00000001

       int i = s;

       long lon = i;

       double d = lon; //1.0

自动类型转换(也叫隐式类型转换)

要实现自动类型的转换,需要满足两个条件,第一两种类型彼此兼容,第二目标类型取

值范围必须大于源类型。所有的数字类型,包括整形和浮点型彼此都可以进行转换。

例如:

byte b=100;

       int x=b;

       System.out.println(x);//程序把b结果自动转换为int类型。

2、 强制类型转换(也叫显式类型转换)

不可以将一个数值赋给范围更小数值范围的变量,除非进行类型转换。

byte b = 100;

       b = b + 2;

       System.out.println(b);

上述例子发生了什么,发生了类型转换。

b+2 遇到了加法运算,2默认是int类型,byte类型b变量存储的值自动类型提升为

了int类型。执行完加法运算后的结果就是int类型,想要将int的类型值放入到byte类型变量b中,无法放入,编译报错。

byte b=1;

       b=(byte)(b+2);

当两种类型彼此不兼容,或者目标类型取值范围小于源类型(目标是byte源是int)

无法自动转换,此时就需要进行强制类型转换。

1、 什么时候要用强制类型转换

   比如小数部分只想保留整数部分.

   一定要清楚要转换的数据在转换后数据的范围内否则会损失精度.

public static void main(String[] args) {

       byte b = 100;

       b = (byte) (b + 2);

       System.out.println(b); // 102

        //舍弃小数部分

        double d=5.5;

       int num=(int)d;

}

2、 表达式的数据类型自动提升

算术表达式,逻辑表达式                                   

所有的byte型、short型和char的值将被提升到int型。

如果一个操作数是long型,计算结果就是long型;

如果一个操作数是float型,计算结果就是float型;

如果一个操作数是double型,计算结果就是double型。

分析 System.out.println(‘a’+1)结果?

自动类型提升

  

byte b = 3;

       int x = 4;

       x = x + b;// b会自动提升为int 类型参与运算。

       System.out.println(x);// 7

强制类型转换

byte b = 2;

       /*

        * 强制类型转换,强制将b+2强制转换为byte类型,再赋值给b

        */

       b = (byte) (b + 2);

       System.out.println(b);// 4

思考1

byte  b=126;

问:既然数据默认的有数据类型,那么126 默认是int类型的,为什么存储到byte类型时不会报错呢。

126 是常量java在编译时期会检查该常量(每个常量)是否超出byte类型的范围。如果没有可以赋值。

思考2:byte b=128;能否正常的编译和运行。

该语句会出现编译错误,128超出了byte变量的存储范围,所以出现编译错误。

文档注释用/** */表示,是java特有的注释,其中注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档。

java中byte变量的范围是  -128~127

 Math.random()的简单使用

 Math.random()可以使系统默认随机选取大于等于0.0且小于1.0的伪随机Double值,是java语言常用的代码

      

int i=(int)(Math.random()*21); 

Scanner的基本使用

Scanner 被称为输入流扫描器类,从控制台读取数据的 String nextLine() 从控制台返回一行,忽略空格。

int: nextInt() 从控制台返回一个 int 型数据,如果时间格式不对将抛出。java.util.InputMismatchException。 long: nextLong() 从控制台返回一个 long 型数据,如果时间格式不对将抛出java.util.InputMismatchException。 float: nextFloat() 从控制台返回一个 float 型数据,如果时间格式不对将抛出java.util.InputMismatchException。 double: nextDouble() 从控制台返回一个 double 型数据,如果时间格式不对将抛出java.util.InputMismatchException。 boolean: hasNext() 判断输入流还有没有下一个数据 ,
首先要好导入包:import java.util.Scanner;或者java.util.*

java.util是一个包名,java.util.*代表该包内的所有类
例子:

 1   import java.util.Scanner;
 2  public class TextScanner{
 3   public static void main(String [] args){
 4 //创建Scanner对象 接受从控制台输入
 5  Scanner input = new Scanner(System.in);
 6  System.out.println("请输入名字:");
 7  //接受String型
 8  String name = input.next();//注意不是nextString()
 9 System.out.println("请输入学号");
10   //接受int型
11  int id = input.nextInt();//什么类型next后面就接什么 注意大小写
12   //输出结果
13  System.out.println("名字为:"+name+"	学号为:"+id);
14    }
15  }


CompareToIgnoreCase的使用

提示: musics[i].compareToIgnoreCase(music) > 0
上面这个方法是比较字符串的方法,
前面的值减 去后面的值,比如 :"aa".compareToIgnoreCase("cc")的值是-2      如果前面的值大返回正数,如果后面的大于前面的,返回负数,或者等于前面的,返回0

例如 “Haha".compareToIgnoreCase("Aha") 是比较 haha 字符串 和 aha字符串 (此方法自动忽略大小写)
h 比 a 大, 所以返回 是 7(相减得来的), (根据字母表顺序)

Java中的构造方法:

就和OC里面的自定义初始化方法一样,为了在创建对象的时候就给对象属性赋初始值,并且只走一次,因为第二次的话又是另一个对象了

 使用构造器时需要记住:

1.构造器必须与类同名(如果一个源文件中有多个类,那么构造器必须与公共类同名)

2.每个类可以有一个以上的构造器

3.构造器可以有0个、1个或1个以上的参数

4.构造器没有返回值,前面不能有 void 

5.构造器总是伴随着new操作一起调用,注意:不是手动调用的,而是java虚拟机自动调用的

举例:

 1 public class A{
 2    public A(){
 3       System.out.println("调用了无参的构造函数");
 4    }
 5    public A(String mess){
 6       System.out.println("调用了有参的构造函数
"+
 7          "参数内容为:"+mess);
 8    }
 9 }
10 public class Test{
11    public static void main(String [] args){
12        A a_1=new A();//调用无参的构造函数
13        A a_2=new A("Hello");//调用有参的构造函数
14    }
15 }

效果图:

在继承中使用构造方法:

默认情况下是自动调用父类的无参构造方法,如果使用super调用父类构造器的语句必须是子类构造器的第一条语句,不信的话,你可以试试,果断的报以下的错误:

如果子类构造器没有显式地调用父类的构造器,则将自动调用父类的默认(没有参数)的构造器。如果父类没有不带参数的构造器,并且在子类的构造器中又没有显式地调用父类的构造器,则java编译器将报告错误

text.java文件代码:

 1  class A{
 2    public A(){
 3       System.out.println("调用了A的无参构造函数");
 4    }
 5    public A(String mess){
 6       System.out.println("调用了A的有参的构造函数
"+
 7          "参数内容为:"+mess);
 8    }
 9 }
10  class B extends A{
11    public B(){
12          System.out.println("调用了B的无参构造函数");
13    }
14    public B(String mess){
15       super(mess);     //如果没有这句就会默认调用父类的无参构造方法
16       System.out.println("调用了B的有参构造函数
"+
17          "参数内容为:"+mess);
18    }
19 }
20 public class text{
21    public static void main(String [] args){
22        B b_01=new B();
23        B b_02=new B("你好");
24    }
25 }

效果图上:

如果把15行的代码删了,就会这样:

toString方法的作用:

Object类提供的toString()方法总是返回该对象实现类的”类名+@+hashCode”值,这个返回值不能真正实现“自我描述”功能如图:

当Java对象和字符串进行连接运算时,系统自动调用Java对象toString()方法返回值和字符串进行连接运算下面代码效果相同

String pStr=p+”字符串”;

StringpStr=p.toString()+”字符串”;

test.java里面的代码:

 1 public class test {    
 2      
 3     public static class User{
 4         String name;
 5         int age;
 6         public User(String name,int age){
 7             this.name = name;
 8             this.age = age;
 9         }
10         @Override
11         public String toString() {
12             return "my name is "+name+",i'm "+age+" years old";
13         }
14          
15     }
16     public static void main(String[] args) {
17         System.out.println(new User("Jack",16));
18     }
19 }

效果图上:

其中,@Override的作用:

 系统可以帮你检查方法的正确性,@Overridepublic String toString(){...}这是正确的一旦写错 写成这样@Overridepublic String tostring(){...}编译器可以检测出这种写法是错误的 这样能保证你的确重写的方确而如果不加@Overridepublic String tostring(){...}这样编译器是不会报错的 它只会认为这是你自己新加的一个方法仅此而已,说白了,就是试图覆盖父类方法而确又写错了方法名时才发挥威力的。

Java中的静态的理解与main函数为什么是静态的?(static)

 首先理解什么是static,java中的static有什么作用?

在C语言中的static表示只初始化一次,而在这java中也一样,不过还多了一些功能,被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。要这个类被加载,Java虚拟机(JVM)就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为: 

类名.静态方法名(参数列表...) 

类名.静态变量

静态方法可以直接通过类名调用,任何的实例也都可以调用,

因此静态方法中不能用thissuper关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。

理解了这些后,我们就可以上代码

1 public class text {    
2 
3     public  void main(String[] args) {
4         System.out.println("dfdfd");
5     }
6 }

编绎通过了,但运行就报错了,如图:

原因是

静态成员函数在执行前必须先构造并实例化该函数所在的类,也就是说必须先创建 一个对象。

如果允许非静态的main,那么main函数所在的类必须先进行实例化,那么就需要再写个函数去实例化main所在的类,再调用main,这个实例化代码又写在哪呢?如果它也是非静态的,那就又要写这个实例化代码,那还有完没完啊??!!因此,没有为什么!JAVA语言就规定了main必须是静态的。

构造方法的前面为什么不能是静态的

我们由浅入深,首先看代码:

 1 public class text {    
 2  class People
 3  {
 4      int id;
 5      String name;
 6      int age;
 7      public People(String name,int age){
 8        this.name=name;
 9        this.age=age;
10        System.out.println(this.name+this.age);
11      }
12  }
13     public static void main(String[] args) {
14         System.out.println(new People("Jack",16));
15     }
16 }

编绎就报错了,如图:

原因是:

this 是指向当前对象的引用,需要对象实例化以后才能赋值。而静态成员都是类所属的,不需要对实例化就可以使用,所以在静态上下文中引用this(可以理解为空指针)时可能其还未赋值,所以应不能这样使用。this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this。说白了,就是不能用类来调用
分析:
People成了text的非静态内部类,属于text的一个成员,在静态方法main中不能访问非静态的成员,也就是说不能直接new Clerk()只能通过外部类的对象访问(创建一个对象)。

所以我们可以这样:

 1 public class text {    
 2  class People
 3  {
 4      int id;
 5      String name;
 6      int age;
 7      public People(String name,int age){
 8        this.name=name;
 9        this.age=age;
10        System.out.println(this.name+this.age);
11      }
12  }
13     public static void main(String[] args) {
14         System.out.println(new text().new People("Jack",16));
15     }
16 }

编绎运行通过 :

Java中有明文规定,类变量不能直接访问实例变量实例变量可以(但不推荐)能访问类变量,所以说一个static修饰的变量在调用普通方法;或一个static修饰的方法在调用普通变量,这是不允许的。

两者的区别是: 

 对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。 
 对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。
总结:
静态的可以访问静态的,静态的不能访问非静态的,非静态的可以访问静态的(因为静态的我个人理解是在JVM编绎时就存在了,与虚拟机共存死亡,而非静态的还不一定存在,所以理解很简单)

如果是在构造方法的前面加上修饰符static ,就会报错,如图:

原因是:

java中构造方法可以有任何访问的修饰符,public、private、protected或者没有修饰符 ,都可以对构造方法进行修饰。不同于实例方法的是构造方法不能有任何非访问性质的修饰符修饰,例如static、final、synchronized、abstract等都不能修饰构造方法。

解释:构造方法用于初始化一个实例对象,所以static修饰是没有任何意义的;多个线程不会同时创建内存地址相同的同一个对象,所以synchronized修饰没有意义;
构造方法不能被子类继承,所以final和abstract修饰没有意义。
2、返回类型是非常重要的,实例方法可以返回任何类型的值或者是无返回值(void),而构造方法是没有返回类型的,void是空类型,所以void也不行。
3、至于命名就是构造方法与类名相同,当然了实例方法也可以与类名相同,但是习惯上我们为实例方法命名的时候通常是小写的,另一方面也是与构造方法区分开。
而构造方法与类名相同,所以首字母一般大写。
注意:构造方法中可以调用普通(实例)方法和构造方法的
直接上代码:调用普通方法
 1 public class text {    
 2  class People
 3  {
 4      int id;
 5      String name;
 6      int age;
 7      public  People(String name,int age){
 8        this.name=name;
 9        this.age=age;
10        System.out.println(this.name+this.age);
11        fun2();
12      }
13 
14      public void fun2(){
15          System.out.println("ceshi2");
16      }
17  }
18     public static void main(String[] args) {
19         System.out.println(new text().new People("Jack",16));
20     }
21 }

效果图上:

构造方法中调用构造方法:

 1 public class text {    
 2  class People
 3  {
 4      int id;
 5      String name;
 6      int age;
 7      public  People(String name,int age){
 8        this.name=name;
 9        this.age=age;
10        System.out.println(this.name+this.age);
11        this();
12        this(20);
13      }
14       public  People(){
15        System.out.println("调用默认的构造方法");
16      }
17       public  People(int age){
18 
19        System.out.println("调用有参数的构造方法,参数是:"+age);
20      }
21     
22  }
23     public static void main(String[] args) {
24         System.out.println(new text().new People("Jack",16));
25     }
26 }

编绎就报错了:

因此得改成这样的:

 1 public class text {    
 2  class People
 3  {
 4      int id;
 5      String name;
 6      int age;
 7      public  People(String name,int age){
 8        this();
 9        //this(20);     //一个构造方法里面只能调用一个构造方法,加上这个就会报错了
10        this.name=name;
11        this.age=age;
12        System.out.println(this.name+this.age);
13      }
14       public  People(){
15            this(20);
16        System.out.println("调用默认的构造方法");
17      }
18       public  People(int age){
19 
20        System.out.println("调用有参数的构造方法,参数是:"+age);
21      }
22     
23  }
24     public static void main(String[] args) {
25         System.out.println(new text().new People("Jack",16));
26     }
27 }

效果图:

结论:在构造方法中可以调用普通方法(对象方法),也可以在构造方法中调用构造方法,格式是:this(参数名,没有的话就不填),并且必须是第一条语句 且只能有一条。

构造代码块的使用与理解:

普通代码块:是最常见的代码块,在方法里用一对“{}”括起来的数据,就是普通的代码块,

构造代码块:是在类中直接定义的,用“{}”括起来的代码。每次调用构造方法前执行,都会先执行构造代码块。

静态代码块:他在类中的成员位置,用“{}”括起来的代码。只不过他用了static修饰了,,且执行一次

 代码块测试题:结合了,普通代码块,构造代码块,静态代码块,是大家能够够清楚的明白代码块执行的数序以及规律

他会先执行class 文件class Nihaoa到内存。所以他会执行class Nihaoa类下的静态块,在执行main方法,编译class GouZao类,然后执行代码,静态的执行一次,构造方法块每次执行

静态内部粝与非静态内部类的使用与理解 

什么是内部类?就是在类中再定义类的类就叫做内部类。

首先先看静态内部类,代码:

 1 public class text {   
 2     int a=0;
 3     static int b=0;
 4 public static class People
 5  {
 6      int id;
 7      String name;
 8      int age;
 9      public  People(String name,int age){
10         this.name=name;
11         this.age=age;
12         fun1();
13         //fun2();
14         //System.out.println("name is:"+name+"  age is:"+a);
15         System.out.println("name is:"+name+"  age is:"+b);
16      }
17  }
18  public  static void fun1(){
19     System.out.println("调用静态的方法");
20  }
21   public  void fun2(){
22     System.out.println("调用非静态的方法");
23  }
24     public static void main(String[] args) {
25         System.out.println(new People("Jack",16));
26     }
27 }

运行通过,效果:

如果把注释部分去掉后,就会报错,如图:

因此,得出:静态内部类的非静态成员(比如this)可以访问外部类的静态变量/静态方法,而不可访问外部类的非静态变量/非静态方法;

再来看非静态内部类:

 1 public class text {   
 2 public  class People
 3  {
 4      int id;
 5      String name;
 6      int static age;
 7      public  People(String name,int age){
 8         this.name=name;
 9         this.age=age;
10         System.out.println("name is:"+name+"  age is:"+age);
11      }
12  }
13     public static void main(String[] args) {
14         System.out.println(new People("Jack",16));
15     }
16 }

运行效果图:

得出:非静态内部类则不能有静态成员。为什么?

假设要访问非静态内部类里的静态成员,由于是非静态内部类,那么必须先声明外部类的实例(也就是对象)才行,内部类也会被初始化,这时就变成对象调用,这就不符合静态的作用了(因为没意义)

其实总结就一句话,静态的可以访问任何静态的,因为在JVM时就分配了内存(个人理解),不能访问非静态的,非静态的可以访问任何静态的,非静态的要访问非静态的,要实例化对象才行。

单例设计模式:

所谓的单例设计模式:顾名思义就是全局就一个对象(一个地址)

 1 /*
 2     单例设计模式 : 一个类只能够创建一个对象出来
 3     软件行业中设计模式23中
 4     可能在java学习中会讲到如下设计模式:
 5         1.单例设计模式
 6         2.观察者设计模式
 7         3.模块设计模式(mvc)
 8         4.装饰设计模式
 9         5.工厂模式
10     
11     设计模式 : 用来解决同一类问题的解决方案(固定的步骤)
12 
13     单例的设置步骤:
14         1.创建一个对象把他设置为私有的静态成员变量,保证对象唯一
15         2.把构造方法设置为私有的,防止new一个对象。
16         3.定义一个公开的静态方法,返回值为上面的对象。
17         
18 
19 */
20 
21 /*
22     oc中单例:
23     +(SingleDog *)default{
24 
25         //保证对象唯一
26         static SingleDog s;
27         if(s == null){
28           s = [[SingleDo alloc] init];
29         }
30         return s;
31     }
32 
33     
34     
35 
36 
37 */
38 
39 
40 //如何实现单例设计模式
41 //--------饿汉单例设计模式
42 class SingleDog{
43     
44     String name;
45     int  age;
46     //保证对象唯一
47     // 声明本类的引用变量, 并且把对象创建出来
48     private static SingleDog  s = new SingleDog(); // 静态的成员变量
49     //私有化构造方法 ,防止通过new来创建对象
50     private SingleDog(){}
51     //提供一个静态方法来接收唯一的对象
52     public static SingleDog getInstance (){
53     
54         return s;
55     }
56 
57 }
58 
59 //------------懒汉单例设计模式--------------
60 //不安全  ,推荐使用上面的写法。
61 class SingleDog2 {
62 
63     //声明本类的引用变量,不创建
64     private static SingleDog2 s;
65     
66     //私有化一个构造方法
67     private SingleDog2() {};
68     
69     //提供一个静态的方法来接收唯一的对象
70     public static SingleDog2 getInstance(){
71         
72         if(s==null){
73             
74             s = new SingleDog2();   
75         }
76 
77         return s;
78 
79     }
80 }
81 
82 class Demo7 {
83     public static void main(String[] args){
84 
85         SingleDog  sd1 = SingleDog.getInstance();
86         sd1.name = "老王";
87         SingleDog  sd2 = SingleDog.getInstance();
88         SingleDog  sd3 = SingleDog.getInstance();
89 
90         System.out.println(sd1);
91         System.out.println(sd2);
92         System.out.println(sd3);
93     }
94 }

在50行和67行用到了private,表示是私有的,外部的类不能访问,如果访问就报错,即对内可见,对外不见,所以我们常常把单例对象封装在一个类中,比如主函数在该类中,那么private就没有意义了,因为有没有都一样的。如:

 1 public  class a{
 2    static class People{
 3      private static People p = new People();
 4        //重写默认的构造方法
 5         private People(){
 6          System.out.println("dfdfdfdfdf");
 7         };
 8         public static People getInstance(){
 9          return p;  
10         }
11     }
12    public static void main(String[] args){
13            People sss = new People();  //这一句没有报错,因此private就没有意义了
14            People s=People.getInstance();
15             People ss=People.getInstance();
16            System.out.println(s);
17           System.out.println(ss);
18          }
19 }

效果图:

抽象类的使用与理解(注意与interface的区别):

abstract(抽象类)的使用(与interface的区别): 

所谓的抽象类就好比一道 抽象的数学题,你一步步做出来了就觉得很简单了,而在java中抽象类是abstract修饰类,会使这个类成为一个抽象类,这个类将不能生成对象实例(因为方法有可能是抽象方法,没有实现,那就没意义了),可以做为对象变量声明的类型,也就是编译时类型,抽象类就像当于一类的半成品,需要子类继承并覆盖其中的抽象方法,不然就会报错,并且抽象方法必须在抽象类中。

标准概念:

面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

代码:

1 public  class a{
2          abstract static class People{
3       }
4    public static void main(String[] args){
5          People p = new People();
6          }
7 }

运行结果:

抽象方法是没有方法体的(也就是没有大括号,只有声明,没有实现,类似于OC中的protocol),留给子类去实现。

1 public  class a{
2          abstract static class People{
3              //abstract void fun();  //这是对的
4              abstract void fun(){}    //不能方法体,这样写是错误的
5       }
6    public static void main(String[] args){
7          }
8 }

编译:

一个抽象类中是可以有非抽象的方法,并且也可以不出现抽象方法的,如:

 1 public  class a{
 2          abstract static class People{
 3              //String name;
 4              //abstract void fun();  //这是对的
 5             // abstract void fun(){}    //不能方法体,这样写是错误的
 6              void fun1(){
 7               System.out.println("haha");  //抽象类中是可以定义非抽象方法的
 8             }
 9       }
10       class Student extends People
11       {
12            public Student(){
13              fun1();
14            }
15       }
16    public static void main(String[] args){
17          Student s = new a().new Student();
18          }
19 }

运行:

一个抽象类中是可以存在构造方法。作用是让子类能过初始化父类中的变量。如:

 1 public  class a{
 2          abstract static class People{
 3              String name;
 4              //abstract void fun();  //这是对的
 5             // abstract void fun(){}    //不能方法体,这样写是错误的
 6              void fun1(){
 7               System.out.println("name is :"+ name);  //抽象类中是可以定义非抽象方法的
 8                
 9             }
10            public People(){   //抽象类的构造方法的作用是用于初始化成员变量
11               name = "yuan";   
12            }
13       }
14       class Student extends People
15       {
16            public Student(){
17              fun1();
18            }
19       }
20    public static void main(String[] args){
21          Student s = new a().new Student();
22          }
23 }

运行:

总结:

1,abstract修饰类,会使这个类成为一个抽象类,这个类将不能生成对象实例,可以做为对象变量声明的类型,也就是编译时类型,抽象类就像当于一类的半成品,需要子类继承并覆盖其中的抽象方法。

2,abstract修饰方法,会使这个方法变成抽象方法,声明(定义)而没有实现,实现部分以";"代替。需要子类继承实现(覆盖)。

3.abstract修饰符在修饰类时必须放在类名前。

4.abstract修饰方法就是要求其子类覆盖(实现)这个方法。调用时可以以多态方式调用子类覆盖(实现)后的方法,也就是说抽象方法必须在其子类中实现,除非子类本身也是抽象类。

5.父类是抽象类,有抽象方法,子类继承父类,并把父类中的所有抽象方法都实现(覆盖),抽象类中有构造方法,是子类在构造子类对象时需要调用的父类(抽象类)的构造方法。

abstract能修饰成员变量吗??

答:不能。原因:只有public, protected, private, static, final, transient 和 volatile 能修饰成员变量。

abstract关键字的使用场景:
我们在描述一个事物的时候,发现这个事物确实存在某种行为,但是这种行为又不具体,那么这个时候就可以抽取这种行为 声明一个没有实现的行为,这种行为就叫抽象的行为,那么这个时候就需要用到抽象类。

使用abstract时需要注意:

1、不能和private一起使用。原因:abstract声明的方法必须要被重写,如果设为private就互相矛盾了

2、不能和static使用。原因:因为static 方法是类方法,必须要有方法体(也就是实现),就像main函数,有且仅有一个,它是不允许子类覆写,而且而abstract方法是没有实现的方法,是必须由子类来覆写的,两者完全矛盾,你说呢?

3、不能和final一起使用。原因:final修饰过的是不能修改的,而且必须要初始化,而abstract必须得重写才行,矛盾了。

原文地址:https://www.cnblogs.com/qq1871707128/p/6056548.html