C++ 中static的含义要比java广得多。
对于c++来说:
1.全局静态变量或者局部静态变量可以让它们相应作用域中的“用户”来使用;
2.类中的静态成员变量和静态成员函数可以用类名访问或者用对象访问(如果权限允许的话),而且其静态成员变量仅能在类外初始化:variable_type CLASSNAME::variable_name = value
。
对于Java而言,因为Java严格遵守oop思想,static仅体现在类的成员变量和方法上。用法同2,但是其初始化可以在类内部完成。
student.java:
package lch;
public class student{
student(){
id++;
}
static public int id = 0;
public int age;
public String name;
}
}
fangfa.java:
package lch;
public class fangfa {
public static void main(String[] args){
student s1 = new student();
System.out.println(s1.id);
student s2 = new student();
System.out.println(s2.id);
}
}
一旦使用static修饰成员方法,该方法即成为静态方法,静态方法不属于对象,而是属于类的。
使用static后,可以且推荐直接通过类名称来使用该方法。
对于本类中的静态方法,可以省略类名称。
静态方法不能直接访问非静态,因为内存中先有静态内容,后有非静态内容。
静态方法中不能使用this,因为没有对应的对象。
student.java
package lch;
public class student{
static int add(int a, int b){
return a + b;
}
}
fangfa.java
package lch;
public class fangfa {
public static void main(String[] args){
student s1 = new student();
System.out.println(student.add(10, 1232)); //建议使用这种写法
System.out.println(s1.add(1234, 3423));
}
}
static内容存放在方法区的静态区内。访问静态内容时不经过对象。
特点:当第一次用到本类时,静态代码执行唯一的一次。
静态内容总是优先于构造方法。
主要用途:一次性地对静态成员变量进行赋值。
student.java:
package lch;
public class student{
student(){
System.out.println("构造方法!");
}
static{
//静态代码块内容
System.out.println("执行!");
}
}
fangfa.java:
package lch;
public class fangfa {
public static void main(String[] args){
student s1 = new student();
student s2 = new student();
}
}
Arrays提供了大量的静态方法,用来实现数组常见操作。
package lch;
import java.util.Arrays;
public class fangfa {
public static void main(String[] args){
int[] a = {
11,42,63,8,9};
String str1 = Arrays.toString(a);
System.out.println(str1);
Arrays.sort(a);
System.out.println(Arrays.toString(a));
}
}
package lch;
public class fangfa {
public static void main(String[] args){
System.out.println(Math.abs(-123)); //绝对值
System.out.println(Math.ceil(123.34)); //向上取整
System.out.println(Math.floor(123.34)); //向下取整
System.out.println(Math.round(123.34)); //四舍五入
}
}
父类正常写:public class Person {}
子类:public class student extends Person{}
如果父类和子类的成员变量重名:
直接通过子类对象访问:等号左边是谁就优先使用谁的值。
简介通过成员方法访问:如果方法在子类定义,使用子类的值。如果方法在父类定义,使用父类的值。
父类的成员变量:super.变量名
子类的成员变量:this.变量名
局部变量:变量名
在继承关系中,方法名称一样,参数列表也一样。
创建子类对象则优先使用子类方法。
注意事项:
1.必须满足方法名称一样,参数列表也一样;
@Override
写在方法前面的注解,用来检测是不是有效的正确覆盖重写。是可选的安全检测手段。
2.子类方法的返回值必须小于等于父类方法的返回值范围;
3.子类方法的权限必须大于等于父类方法的权限修饰符。
public > protected > (default) > private
同C++。
可以通过super关键字调用父类的重载构造。
super的父类构造调用一定是子类构造方法的第一句。
1.在子类的成员方法中访问父类成员变量;
2.在子类的成员方法中访问父类成员方法;
3.在子类的构造方法中访问父类构造方法。
1.在本类的成员方法中访问本类的成员变量;
2.在本类的成员方法中访问本类的另一个成员方法;
3.在本类的构造方法中访问本类的另一个构造方法。此时this也必须是构造方法的第一个语句。
super和this两种构造调用不能同时使用。
1.单继承;
2.多级继承;
3.一个子类只有一个直接父类,一个父类可以拥有多个子类。
如果父类不确定如何进行方法实现,那么这就应该是一个抽象方法。
抽象方法所在的类必须是抽象类。使用abstract
关键字。
Animal.java:
package lch;
public abstract class Animal {
public abstract void eat();
}
不能直接创建抽象类对象。必须用一个子类继承抽象父类,且子类必须覆盖重写父类的所有抽象方法。
Cat.java:
package lch;
public class Cat extends Animal{
public void eat(){
System.out.println("吃鱼");
}
}
1.抽象类不能创建对象;
2.抽象类中可以有构造方法;
3.抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类,没有抽象方法的抽象类也不能直接使用;
4.抽象类的子类必须覆盖重写父类的所有抽象方法,否则此子类仍为抽象类。
一种公共的规范标准。
接口是多个类的公共规范。
接口是引用数据类型,最重要的是其中的抽象方法。
接口中可以包含的内容有:
1.常量
2.抽象方法
3.默认方法
4.静态方法
5.私有方法
接口中的抽象方法,修饰符必须是固定的两个修饰符:public abstract
,可以部分或全部省略。
MyInterfaceAbstract.java:
package lch;
public interface MyInterfaceAbstract {
public abstract void method_abs1();
public void method_abs2();
abstract void method_abs3();
void method_abs4();
}
接口不能直接使用,必须有一个实现类来实现该接口。
接口的实现类必须覆盖重写接口的所有抽象方法。如果没有全部重写,那这个类必须为抽象类。
MyInterfaceImpl.java:
package lch;
public class MyInterfaceImpl implements MyInterfaceAbstract{
@Override
public void method_abs1() {
System.out.println("方法1");
}
@Override
public void method_abs2() {
System.out.println("方法2");
}
@Override
public void method_abs3() {
System.out.println("方法3");
}
@Override
public void method_abs4() {
System.out.println("方法4");
}
}
默认方法可以解决接口升级的问题。
实现类中没有重写的方法,会到接口中寻找默认方法。
MyInterfaceAbstract.java:
package lch;
public interface MyInterfaceAbstract {
public default void method_abs1(){
System.out.println("默认方法1");
};
public default void method_abs2(){
System.out.println("默认方法2");
};
}
MyInterfaceImpl.java:
package lch;
public class MyInterfaceImpl implements MyInterfaceAbstract{
@Override
public void method_abs1(){
System.out.println("方法1");
}
}
不能通过接口实现类来调用接口中的静态方法。应该通过接口名称直接调用静态方法。
MyInterfaceAbstract.java:
package lch;
public interface MyInterfaceAbstract {
public static void method_abs1(){
System.out.println("静态方法1");
}
}
MyInterfaceImpl.java:
package lch;
public class MyInterfaceImpl implements MyInterfaceAbstract{
}
MyInterfaceAbstract.java:
package lch;
public interface MyInterfaceAbstract {
public static void method_private1(){
method_default1();
method_default2();
}
private static void method_default1(){
System.out.println("静态方法1");
}
private static void method_default2(){
System.out.println("静态方法2");
}
}
MyInterfaceImpl.java:
package lch;
public class MyInterfaceImpl implements MyInterfaceAbstract{
}
接口当中可以使用成员变量,但必须用public static final
修饰,可以省略但效果一样。从效果上看就是常量。
MyInterfaceAbstract.java:
package lch;
public interface MyInterfaceAbstract {
//常量,一旦赋值,不能修改:
public static final int NUM = 10;
}
MyInterfaceImpl.java:
package lch;
public class MyInterfaceImpl implements MyInterfaceAbstract{
}
接口没有静态代码块和构造方法。
一个类的直接父类只能有一个,但可以同时实现多个接口,格式为public class C implement A, B
。
如果实现的多个接口存在同名方法,那么只需要重写一次。
如果实现的多个接口存在同名的默认方法,那么必须对冲突的默认方法进行重写。
如果父类方法与接口方法冲突,那么优先使用父类方法。
1.类与类之间是单继承的;
2.类与接口之间是多实现的;
3.接口与接口之间是多继承的;
4.多个父接口中的抽象方法重复是没有关系的,但默认方法重复则子接口必须重写。