Java基础知识,涉及继承、多态、static、super、this、instanceof等关键字。equals、toString等方法以及Object类,泛型数组使用等等
一、继承的理解
- 继承:简单通俗的来讲,继承就是一个类继承另一个类,通常用extends表示继承。
- 继承的类叫子类,被继承的类叫父类。
- 子类可以使用父类的变量和方法,同时也可以重写父类的方法。
- 在Java中没有多继承这一概念,但是有类似多继承的方法!(通常来讲一个父类可以有多个子类,而一个子类只能有一个父类)
| |
| public class Son extends Father{ |
| |
| } |
| class Father { |
| |
| } |
二、super、this、instanceof关键字
this
- 上一篇文章已经说过了方法重写的概念,在这里就不再重复了。
- this关键字也在上一篇讲过,我们可以在构造器中通过this()来调用本类的不同参数构造器。通常我们都写在第一行!
- 还可以通过
this.变量
的方式表示使用的是本类的变量
super
- super关键字就是在继承中应用的,我们可以通过super()调用父类的不同参数构造器
- 同时还可以通过
super.方法
,调用父类的方法。
- 同时它也是写在第一行!
- 通常使用super是因为子类继承了父类,这样子类就不必要在写一些成员变量,直接在构造器中通过super()调用父类的构造器,将参数初始化即可。
| public class Son extends Father{ |
| Son(String name, int age) { |
| super(name, age); |
| } |
| } |
| class Father { |
| String name; |
| int age; |
| Father(String name,int age) { |
| this.name = name; |
| this.age = age; |
| } |
| } |
| |
对于继承简言之就是:父类有的子类都有,父类没有的子类也可以有
instanceof
| public void instanceOf(Animal T) { |
| if(T instanceof Dog) { |
| |
| t = (Dog) T; |
| System.out.println("yes"); |
| } |
| } |
| Animal dog = new Dog(); |
| Animal cat = new Cat(); |
| cat.instanceOf(dog); |
三、多态
- 多态是在继承的基础上实现的。也称之为(向上转型)
- 大家只需要记住对于成员变量:编译看左边,运行也看左边。
- 而对于方法:则是编译看左边,运行看右边。
| public class Animal { |
| public void play() { |
| System.out.println("玩"); |
| } |
| public void eat() { |
| System.out.println("吃"); |
| } |
| } |
| public class Cat extends Animal{ |
| public void eat() { |
| System.out.println("猫吃饭,亲密度+8"); |
| } |
| public void play() { |
| System.out.println("撸猫,体力值-9"); |
| } |
| } |
| public class Test { |
| public static void main(String[] args) { |
| Animal cat = new Cat(); |
| |
| cat.eat(); |
| cat.play(); |
| |
| |
| |
| } |
| } |
Animal cat = new Cat();这也是向上转型,将Cat类的转成了Animal
3.1abstract
- 抽象类:使用abstract关键字
- 抽象类中的方法不需要实现,只需要声明占一个位置就行。我们可以在子类中去具体实现这个方法。
- 这样更有灵活性,就像我们定义了一个抽象方法eat(),而不同的子类可以去实现成不同的方法,猫可以实现吃鱼,狗可以实现吃翔,使程序更加简单化。
- 抽象类无法实例化,也就不能造对象了。
3.2权限修饰
- 再次总结权限修饰范围
- 仅对本类可见————private
- 对外部完全可见————public
- 对本包和所有子类可见————protected
- 对本包可见————缺省,也就使默认的
四、Objcet
- Object是所有类的父类
- 既是没有明显写出继承Object,但也默认认为Object是父类
4.1equals方法
- Object类中的equals()方法比较的是内存地址,通常我们都会重写equals()方法,达到值比较的目的。
- getClass方法将返回一个对象所属的类。我们可以通过它检测两个对象是否属于同一个类。
Java规范要求equals方法具有下面的特性:
1.自反性:对于任何非空引用x,x.equals(x)应该返回true。
2.对称性:对于任何引用x和y,当且仅当y.equals(x)返回true时,x.equals(y)返回true。
3.传递性:对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)也应该为true。
4.一致性:如果x和y引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果。
5.对于任意非空引用x,x.equals(null)应该返回false。
- 但是对于一个e是Employee对象,m是Manager对象,并且两个对象的值都是相同的。如果调用e.equals(m)则返回true。若反过来调用m.equals(e)则返回false。这就违反了我们的对称性。
- 因为我们用的是instanceof检测的,但是子类instanceof父类是无法进行的。所以这也是instanceof的缺点
- 我们可以通过getClass来比较两个对象是否属于同一个类,但是这样也有限制,就是多态的情况下返回false。
如何正确重写equals方法:
- 比较常见的两种重写方法:
- 用
instanceof
实现重写equals
方法
- 用
getClass
实现重写equals
方法
| class Son extends Father{ |
| public static void main(String[] args) { |
| Son son = new Son(); |
| Father father = new Father(); |
| Father sss = new Son(); |
| System.out.println(father.equals(son)); |
| |
| } |
| } |
| class Father{ |
| public boolean equals(Object obj) { |
| if(this == obj) return true; |
| |
| |
| |
| |
| |
| System.out.println(obj.getClass()); |
| if(obj == null || !(obj instanceof Father)) { |
| return false; |
| } |
| Father obj1 = (Father) obj; |
| return true; |
| } |
| } |
- 这里instanceof的缺点就是,父类调用比较子类为true,子类调用比较父类为false,所以我们可以尽量调用父类的equals来避免这个问题。
- 同时也可以使用getClass进行判断,是否为同一个类对象。
4.2hashCode方法
点击查看代码
| int hash = 0; |
| for(int i = 0; i < length(); i++) { |
| hash = 31*hash + charAt(i); |
| } |
- 对于字符串的散列码,是看字符串的内容而定的。意味着两个字符串内容相同,则他们的散列码也相同。
4.3toString方法
- 其实这个方法非常简单,就是把我们的字段以字符串的形式,好看的输出出来。
| @Override |
| public String toString() { |
| return getClass().getName() |
| +"{" |
| + "tili=" |
| + tili |
| + ", qimi=" |
| + qimi |
| + '}'; |
| } |
- 在使用的时候我们可以写成
System.out.println(x.toString());
System.out.println(x);这样会默认调用toString()方法,可以简略不写
但是在有时候我们用toString方法是会出现输出java.io.PrintStream@2f6684和[I@1a46e30的情况
1.这是因为Objcet类定义了toString方法,可以打印对象的类名和散列码,所以需要我们对toString方法进行重写
2.数组也继承了Objcet类的toString,如果我们使用时不重写toString,则会出现[I@1a46e30
,补救办法就时使用Arrays.toString()
3.若是二维数组,则可以使用Arrays.deepToString()方法
4.强烈建议在每一个类中都重写toString方法。
五、泛型数组列表
- 在做题时,必须确定数组的长度以后才能够使用,这样使我们非常的不方便!
- 所以我们就可以使用一个动态扩容的数组,这样就不必定义它的初始化长度。
- ArraysList list = new ArrayList<>(100) 这是初始化100的数组,可动态扩容
- 如果说空间过多浪费了,可以使用trimToSize()方法,将没用过的空间释放掉。
- 具体详细的ArrayList用法,我们在日后的集合学习。
5.1将字符串转成整型
int x = Integer.parseInt(s);
5.2将数字转成字符串
String s = String.ValueOf(x);
5.3可变参数
| System.out.println(sum(1,2,3,4,5)); |
| public static int sum(int... a) { |
| int total = 0; |
| for(int i:a) { |
| total += i; |
| } |
| return total; |
| } |
六、枚举类
- 枚举用enum表示
- public enum Size{1,2,3,4,5};一次自增1
- 枚举的构造器总是私有的
七、结尾
- 对于继承、多态内容就总结这么多,希望大家可以多多练习。如果有不足之处,希望大家多多包涵,多多支持。如果有不懂的地方可以直接私信问我,欢迎来访!
- 我将会继续更新关于Java的学习知识,感兴趣的小伙伴可以关注一下。
- 文章写得比较走心,用了很长时间,绝对不是copy过来的!
- 尊重每一位学习知识的人,同时也尊重每一位分享知识的人。
本文作者:lx-meteor
本文链接:https://www.cnblogs.com/lx-meteor/p/16095211.html
版权声明:本作品采用lx-Meteor许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步